Table of Contents
Introduction
In Rails, helpers, presenters or decorators both work for design patterns used for the view logic, Making the view cleaner or more maintainable. Both patterns aim to extend the functionality of the model and controllers but they are slightly different in their way.
Let's walk through examples of using a helper, presenter, and decorator to handle the same task: displaying a user's full name and their formatted signup date.
Scenario:
User Model has the first_name and last_name created_at attributes. We want to display the full name of the user and formatted signup date in a view.
Using helper
1. Model
class User < ApplicationRecord
attributes: first_name, last_name and created_at
End
2. Helper
module UserHelper
def full_name(user)
“#{user.first_name} #{user.last_name}”
end
def date_fromat(user)
user.created_at(“Y%, m%, d%”)
end
end
3. Controller
def show
@user = User.find(params[:id])
end
4. View
<%= date_format(user) %>
<%= full_name(user) %>
Using presenters
app/presenters/users_presenter.rb
1. Presenter
class UsersPresenter
def initialize(@user)
@user = user
end
def full_name
“#{@user.first_name} #{@user.last_name}”
end
def sign_up_date
“#{@user.create_at}”
end
end
2. Controller
def show
@user = User.find(params[:id])
@user_presenter = UsersPresenter.new(@user)
end
3. View
<%= @user_presenter.full_name %>
<%= @user_prsenter.sign_up_date %>
Using a Decorator (with Draper Gem)
app/decorator/user_decorator.rb
1. Decorator
class EmployeeDecorator < Draper::Decorator
delegate_all
def full_name
"#{object.name} #{object.email}"
end
def sign_up_date
object.created_at.strftime("%Y/ %b/ %M")
end
end
2. Controller
def show
@user = User.find(params[:id]).decorate
End
3. View
<%= @user.full_name %>
<%= @user.sign_up_date %>
Comparison of use cases
1. Helper
- Best for simple, reusable logic that doesn't need to maintain state.
- Can quickly become cluttered if used for complex or too much logic.
- Example: Useful for simple formatting methods that don't involve complex interactions or dependencies.
2. Presenter
- Handling more complex view logic and when you need to format or manipulate data from multiple models.
- Encapsulates presentation logic into a dedicated class, keeping views and controllers clean.
- Example: Useful when you need to combine data from multiple models or perform complex data manipulation before presenting.
3. Decorator
- Best for extending model functionality in a modular and reusable way, especially when using a library like Draper.
- Example: Useful when you want to keep model logic focused on data and business rules while offloading view-specific methods
When to use which
Use helper when:
1. Simple, Reusable Logic
- Helpers are ideal for simple, repetitive tasks that need to be used across multiple views.
- Example: Formatting a date, generating a common piece of HTML.
2. No Need for State:
- Helpers are best when the logic does not need to maintain state or rely on instance variables.
- Example: A method to display a user’s role.
Use Presentor when:
1. Complex View Logic:
- Presenters are suited for encapsulating complex view logic, especially when it involves multiple models.
- Example: Displaying a user’s profile with data from various related models.
2. Clean data and View:
- They help keep your view templates clean by moving logic into a dedicated object.
- Example: Formatting user data and combining related information.
Use Decorator when
1. Dynamic Behavior:
- When you need to dynamically add behavior to model instances at runtime.
- Example: Applying different decorators based on the context in which the model is used.
2. Clean data and View:
- They help keep your view templates clean by moving logic into a dedicated object.
- Example: Formatting user data and combining related information.
Conclusion
Each approach has its strengths and ideal use cases. Helpers are great for simple and small view logic, presenters work well for encapsulating complex view logic and handling multiple models, and decorators are excellent for extending and enhancing model instances with additional view-specific methods. Choose the approach that best fits the complexity and structure of your view logic.