12/08/2018, 16:39

Decorator In Ruby on Rails

With this article I want to show you guy about one technech of ruby on rails that is called Decorator. It is an object-oriented layer of presentation logic to your Rails Application. We can image it that without decorator, the functionality might have been tangle up. with this article too, you ...

With this article I want to show you guy about one technech of ruby on rails that is called Decorator. It is an object-oriented layer of presentation logic to your Rails Application. We can image it that without decorator, the functionality might have been tangle up. with this article too, you heard about why the reason we need to use decorator in ruby on rails appplication with practice code and you can apply it into your application ruby on rails. So in this article I will show you introduce you guy about one gem in ruby on rails that's call draper.

The decorator pattern is a design pattern that allows behavior to be added to an individual object without affecting the behavior of other objects from the same class. We can check it with the simple example.

   @movie = Movie.find(1)

We can add additional behaveior to an instantiated model like @movie, before we pass it from controler to view. However, in other context, the Movie model, doesn't have the added behavior that's the result tof the decoration. example

movie.create_at 
// Mon, 16 Oct 2017 04:17:21 UTC +00:00

But we want to show result of movie.created_at is 2017-11-16. So decorator can help to do that.

To understand more about this, we need to one simple project about draper gem that allow us to use decorator in ruby on rails.

Project demo

  • create new rails application that is called draper-app-demo
 rails new draper-app-demo
 bundle install
  • For my design database on this project, I will create simple as below, we have 2 model: Book and Author with simple design as image below:
  • let's create two models follow design
rails db:create
rails g model author name:string
rails g model book published_at:datetime author:references
rails db:migrate

Now we can add gem draper into your file Gem file with gem 'draper', '~> 3.0.1' and you need to run bundle. After that we need to create ApplicationDecorator that all generated decorators inherit from, run...

rails generate draper:install

After that we need to have draper installed and generate for each our resource

rails generate decorator  Book
rails generate decorator  Author

Usage

When writing decorator methods you'll usually need to access the wrapped model. While you may choose to use delegation (covered below) for convenience, you can always use the object (or its alias model). On file app/decorators/book_decorator.rb

class BookDecorator < ApplicationDecorator
  delegate_all
  
  def published_at
      object.published_at.strftime("%m/%d/%Y")
  end
end
class AuthorDecorator < ApplicationDecorator
  delegate_all
  
  def name
      "#{object.name}  this is name"
  end
end

after we config as before we test it, book.decorate.published_at , author.decorate.name will be display other format. we need to work it with view and controller, by generate:

rails g controller books

To use Draper in our Book page we first need to make a change to the show action in the BooksController. This action currently fetches a Book in the usual way.

class BooksController < ApplicationController
  def show
    @book = Book.find(params[:id])
  end
end

We need to wrap this user in our decorator which we do by replacing Book.find with BookDecorator.find. on /app/controllers/books_controller.rb

def show
 @book = BookDecorator.find(params[:id])
end

This code will now return a BookDecorator instance that wraps the Book record and delegates all methods to it by default (more on this later). The action will still work as it did before even though we’re working with a BookDecorator instead of a Book. Now we can start to clean up our views and we’ll begin with the code that renders the book’s published_at. app/decorators/book_decorator.rb

------
  decorates_finders

  def published_at
    if object.published_at.present?
      object.published_at.strftime("%m/%d/%Y")
    else
      "Not yet to add published"
    end
  end

Next we’ll tidy up the code that renders the book’s name. We’ll replace this code in the view: app/views/users/show.html.erb

<h1><%= @book.published_at %></h1>
  • when published_at is not present
  • when published_at is present

Conclusion

Decorators to a Rails application’s views much like a presenter pattern. If you find that you have a lot of complex view logic in your templates and helper methods Draper can help to clean up this code by taking a more object-orientated approach.

  • source project
0