gem Draperを初めて使用したので振り返り
はじめに
今回、初めてDraper
を使用したのでまとめとして書いています。
Draperとは?
ざっくりいうとDecorator
を導入するのに便利なgemです。
Decoratorとは?
こちらの記事が凄く分かりやすかったです。
Decorator と Presenter を使い分けて、 Rails を ViewModel ですっきりさせよう - KitchHike Tech Blog
Decoratorの役割とDraperについて - Qiita
DecoratorとはViewModel
の一種です!!(記事を参考にしています)
もう少し言いますと単一のモデルクラス
に対応するViewModelです。
viewに表示用のロジックを直接書いていった場合に規模が大きくなるにつれて、
重複する部分が発生する可能性があります。
そうなると、保守性が低下してしまうという弊害が発生してしまいます。
これを回避しようすると以下のような事を思いつくと思います。
Modelに切り出す
リファクタリングの一つにControllerは薄く、Modelは厚く
という考えがあります。
しかし、表示用のロジックが多くなるにつれてModelが肥大化し、見通しが悪く
なります。helperに切り出す
helperを使用する場合はmodelに関連しない
表示ロジックを記載するのがいいです。
また、helperにはscopeの問題があります。viewでは全てのhelperが参照できる為、
メソッド名が衝突する可能性があります。
こちらの記事が分かりやすかったです。ViewModel
に切り出す(<= やること!!)
viewに関するロジックを切り出してViewModel
モデルに集約する。
導入方法
こちらを参考にしてください。
rails generate draper:install
# => decorators/application_decorator.rbを作成します。
Decoratorを作成するには以下を実行します。
$ rails generate decorator User # Userモデルがあるという前提です!! # => decorators/user_decorator.rbを作成します。
中身を見ています
decorators/user_decorator.rb class UserDecorator < Draper::Decorator delegate_all end
delegate_all
メソッドはDecorator内にないメソッドが呼び出された場合、
Model(ここではUser)のメソッドを呼び出します。
helperにアクセスする場合
h
メソッドでアクセスできる。(Rails,自作両方可)helpers
でもアクセス可能。
class ArticleDecorator < Draper::Decorator def emphatic h.content_tag(:strong, "Awesome") end end
Modelにアクセスする場合
class ArticleDecorator < Draper::Decorator def published_at object.created_at.strftime("%A, %B %e") # <= objectでアクセス可能 model.created_at.strftime("%A, %B %e") # <= modelはエイリアス end end
delegate_allが宣言されている場合
先程のobjectを省略できます。
class ArticleDecorator < Draper::Decorator delegate_all def published_at created_at.strftime("%A, %B %e") end end
オブジェクトをDecorateする方法
- オーソドックス
モデル名からDecoratorを推測するので、両方の名前を合わせる必要がある。
@user = User.find(params[:id]).decorate
名前が異なる場合でも以下のようにするとdecorateできる。
@user = ProductDecorator.new(User.first) @user = ProductDecorator.decorate(User.first)
注:allを使用してオブジェクトを取得する場合、rails3
だと配列
を返すのでdecorate_collection
を使う。
#rails3まで @users = UserDecorator.decorate_collection(User.all) # rails3以降ではdecorateでok @users = User.all.decorate
他にも様々なメソッドが用意されています!!
是非、参考サイトにアクセスして確認してください!!
参考
GitHub - drapergem/draper: Decorators/View-Models for Rails Applications