14
Decorator in Ruby on Rails
Decorators provide a flexible alternative to subclassing for extending functionality. Simple! 😉
There are several ways to implement it, but the easiest for me is using Draper gem.
> rails new decorator-rails
> bundle add draper
Well, from this moment when we create a controller it will automatically create our decorator file in app/decorator
folder.
> rails g scaffold User first_name last_name
Among other files, the file app/decorators/user_decorator.rb
has been created automatically.
# app/decorators/user_decorator.rb
class UserDecorator < Draper::Decorator
delegate_all
def full_name
object.first_name + ' ' + object.last_name
end
end
That allows behavior to be added to an individual object without affecting the behavior of other objects from the same class.
# app/controllers/users_controller.rb
def show
@user = User.find(params[:id]).decorate
end
# app/views/users/show.html.erb
First name: <%= @user.first_name %>
Last name: <%= @user.last_name %>
Full name: <%= @user.full_name %>
And now your view logic has been abstracted and organized to where it should be. This will greatly help you to reduce the code in your view files.
Usually it is used with Presenters, but I prefer to do it in another post 😉
🔍 Recommended reading
Thank you for reading 🙏
El patrón Decorator nos permite poder encapsular un objeto para que podamos extender su funcionalidad antes de su instanciación, así de simple! 😉
Existen muchas formas de implementarlo, pero una de las más sencillas es hacerlo con la gema Draper.
> rails new decorator-rails
> bundle add draper
Bien, a partir de este momento cuando nosotros creemos un controlador, automáticamente se creará también su decorador en el directorio app/decorator
.
> rails g scaffold User first_name last_name
Además de otros archivos, el fichero app/decorators/user_decorator.rb
ha sido creado automáticamente.
# app/decorators/user_decorator.rb
class UserDecorator < Draper::Decorator
delegate_all
def full_name
object.first_name + ' ' + object.last_name
end
end
Esto nos permite agregar comportamiento a un objeto individual sin afectar al comportamiento de otros objetos de la misma clase.
# app/controllers/users_controller.rb
def show
@user = User.find(params[:id]).decorate
end
# app/views/users/show.html.erb
First name: <%= @user.first_name %>
Last name: <%= @user.last_name %>
Full name: <%= @user.full_name %>
Y ahora su lógica de vista se ha abstraído y organizado donde debería estar. Esto le ayudará enormemente a reducir el código en sus archivos de vista.
Normalmente es usado conjuntamente con el patrón Presenters, pero he preferido hacerlo en otro post 😉
🔍 Lecturas recomendadas
Gracias por leer 🙏
14