DEV Community

Victor Hazbun
Victor Hazbun

Posted on

Refactoring towards decorators in Rails

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.

Top comments (1)

Collapse
 
fernandomaia profile image
Fernando Maia

Nice and clean solution. Awesome!