Putting presentation logic in controller is a good practice in Ruby? Putting presentation logic in controller is a good practice in Ruby? ruby-on-rails ruby-on-rails

Putting presentation logic in controller is a good practice in Ruby?


You are not the first to wonder this. If views and controllers should have little to no logic, and the model should be presentation agnostic, where does presentation logic belong?

Turns out we can use an old technique called the decorator pattern. The idea is to wrap your model object with another class that contains your presentation logic. This wrapper class is called the decorator. The decorator abstracts away logic from your view, while keeping your models isolated from their presentation.

Draper is an excellent gem that helps define decorators.

The sample code you gave could be abstracted like so:

Pass a decorator to the view with @user = UserDecorator.new current_user in your controller.

Your decorator could look as below.

class UserDecorator  decorates :user  def welcome_message    if user.admin?      "Welcome back, boss"    else      "Welcome, #{user.first_name}"    end  endend

And your view would simply contain @user.welcome_message

Notice that the model itself doesn't contain the logic to create the messages. Instead, the decorator wraps the model and translates model data into a presentable form.

Hope this helps!


I would use a helper for this. Suppose you have to translate the welcome-message, based on some locale.

In the app/helper/user_helper.rb write

module UserHelper  def welcome_message(user)    if user.admin?      I18n.t("admin_welcome_message", :name => user.name)    else      I18n.t("user_welcome_message", :name => user.name)    end  end end

and in your view you can then just write

<%= welcome_message(user) %>

Note that the decorator/presenter offers a really clean object-oriented approach, but imho using a helper is much simpler and sufficient.


No, you don't want any conditionals at all in the user class nor the controller. The point of that example on the blog post is to make reference to polymorphism, just good old fashioned OO design.

# in application_controller for exampledef current_user  if signed_in?    User.find(session[:user_id])  else    Guest.new  end  end#app/models/user.rbclass User   def welcome_message     "hello #{name}"   endend#app/models/guest.rbclass Guest  def welcome_message    "welcome newcomer"  endend

...you get the idea.

Only, instead of littering your model with presentation-only methods, create a decorator that acts as a presenter:

require 'delegate'class UserPresenter < SimpleDelegator  def welcome_message    "hello #{name}"  endend

And now current_user looks like so:

# application_controllerdef current_user  if signed_in?    UserPresenter.new(User.find(session[:user_id]))  else    Guest.new  endend