Draperを使ってみる

Draperとは?

Draperはデコレーター(ビューとモデルの中間の処理を引き受ける)で、railsのプレゼンテーション層を担う。 表示に関するロジックをプレゼンテーション層に引き渡すことで、以下のようなことが避けられる。

  • モデルに表示ロジックを記述
  • ビューファイル内のif文多用
  • helperの名前空間の衝突

結果、コードの可読性、保守性を向上することができる。

draperをインストー

gem 'draper', '~> 1.3'

$ bundle install

土台となるアプリケーションを作成

$ rails g scaffold Blog title:string content:text f:id:maru877:20170727200954p:plain draperをインストールしているため、decoratorsも作成されます。

$ rails db:migrate

生成されたコード

class BlogDecorator < Draper::Decorator
  delegate_all

  # Define presentation-specific methods here. Helpers are accessed through
  # `helpers` (aka `h`). You can override attributes, for example:
  #
     def created_at
       helpers.content_tag :span, class: 'time' do
         object.created_at.strftime("%a %m/%d/%y")
       end
     end

end

delegate_allとは、decoratorに存在しないメソッドがコールされた場合、モデルの処理が実行される。

controllerにてdecoratorインスタンスを作成する。

オブジェクトをデコレートする(decorator内で利用できるようにする)ためには、以下の方法を利用します。 - 複数のオブジェクトの場合、decorate_collection - 単体のオブジェクトの場合、decorate

class BlogsController < ApplicationController
  before_action :set_blog, only: [:show, :edit, :update, :destroy]

  # GET /blogs
  # GET /blogs.json
  def index
    @blogs = BlogDecorator.decorate_collection(Blog.all)
  end

...

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_blog
      @blog = BlogDecorator.decorate(Blog.find(params[:id]))
      # これでもいける(model名からdecoratorを推察してくれる)
      # Blog.find(params[:id]).decorate 
    end
end

このようにデコレーターインスタンスを生成します。

ビューからdecoratorメソッドを利用する。

app/views/blogs/index.html.erbを編集。

<p id="notice"><%= notice %></p>

<h1>Blogs</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @blogs.each do |blog| %>
      <tr>
        <td><%= blog.title %></td>
        <td><%= blog.content %></td>
        <td><%= blog.created_at %></td>
        <td><%= link_to 'Show', blog %></td>
        <td><%= link_to 'Edit', edit_blog_path(blog) %></td>
        <td><%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Blog', new_blog_path %>

表示を確認する

f:id:maru877:20170727200934p:plain

draperで定義したメソッドcreated_atがコールされていることが確認できる。

参考

こちらを参考にさせていただきました。
http://ruby-rails.hatenadiary.com/entry/20150415/1429031791