Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Some recommendation [1] suggest you to use

<%= current_user.welcome_message %>

instead of

<% if current_user.admin? %>
  <%= current_user.admin_welcome_message %>
<% else %>
  <%= current_user.user_welcome_message %>
<% end %>

But the problem is you must have the decision logic somewhere in your code.

My understanding is putting the decision in template is better than controller as it make your controller more clean. Is it correct?

Are there better way to handle this?

http://robots.thoughtbot.com/post/27572137956/tell-dont-ask

like image 828
Howard Avatar asked Jul 27 '12 04:07

Howard


1 Answers

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
  end
end

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!

like image 153
cjhveal Avatar answered Oct 21 '22 03:10

cjhveal