DEV Community

loading...

Refactoring towards decorators in Rails

Victor Hazbun
Founder at @BonsaiLabs
・1 min read

Decorators

They wrap an object and extend its functionality without modifying the object itself.

The problem

Say you have the following view.

 <p>Name: <%= @company.name.titleize %></p>

 <p>Email: <%= @company.email_private? 'Private' : @company.email %></p>

 <p>Sign Up At: <%= @company.sign_up_at.strftime('%d. %m. %Y.') %></p>
Enter fullscreen mode Exit fullscreen mode

It's bad because the view should not care about how to display the data, it should just display it.

The Decorator object

class CompanyDecorator < SimpleDelegator
  def display_name
    name.titleize
  end

  def protected_email
    return "Private" if email_private?
    email
  end

  def formatted_sign_up_at
    sign_up_at.strftime("%d %b %Y")
  end
end
Enter fullscreen mode Exit fullscreen mode

The implementation

Nice, let's see how the controller looks now.

class CompanyController < ApplicationController
  def show
    company = Company.find(params[:id])
    @decorated_company = CompanyDecorator.new(company)
  end
end
Enter fullscreen mode Exit fullscreen mode

Now, the view

 <p>Name: <%= @decorated_company.display_name %></p>

 <p>Email: <%= @decorated_company.protected_email %></p>

 <p>Birthday: <%= @decorated_company.formatted_sign_up_at %></p>
Enter fullscreen mode Exit fullscreen mode

Final thoughts

Not only looks better, testing this approach is much simpler.

This does not only applies for Rails apps, this pattern could be used anywhere in Ruby.

Discussion (1)

Collapse
fernandomaia profile image
Fernando Maia

Nice and clean solution. Awesome!