Decoratorとは、、?
既存のオブジェクトを新しいDecoratorオブジェクトでラップすることで既存の関数やクラスの中身を直接触ることなく、その外側から機能を追加したり書き換えたりする。また、既存のクラスを拡張する際にクラスの継承の代替手段として用いられます。
「(プログラムで管理しやすい)データ」を「(ユーザーが理解しやすい)情報」に変換する役割。使うためには「draper」というgemをインストールして利用する。app/decorators配下にファイルを生成する。
##使い方
1.Gemfileに以下を記述する。
gem 'draper'
合わせてこちらも実行する。
$ budle install
2.以下コマンドを実行して、application_decorator.rb を作成する。
$ rails generate draper:install
3.以下コマンドを実行してデコレーターを作成する。
# rails generate decorator モデル名
$ rails generate decorator Article
モデル
app/decorators/article_decorator.rb
class ArticleDecorator < Draper::Decorator
delegate_all
def publication_status
if published?
"Published at #{published_at.strftime("%A, %B %e")}"
else
"Unpublished"
end
end
end
ビュー
・
・
・
<%= @article.publication_status %>
・
・
・
##小技集
- モデルインスタンスにアクセス
object.published_at.strftime("%A, %B %e")
model.published_at.strftime("%A, %B %e") # modelはobjectのalias
- 全てのメソッドを委譲
- 内部的にはmethod_missingを使い委譲している
- メソッド探索の順番: デコレータ -> 親デコレータ -> モデル
class ArticleDecorator < Draper::Decorator
delegate_all
end
- 指定のメソッドを委譲
- deleageメソッドはActive Supportのdelegateとほぼ同じ。ただしto: :objectを省略できる。
class ArticleDecorator < Draper::Decorator
# titleで、object.titleにアクセスできるようになる
delegate :title, :body
# 指定のメソッドを指定したオブジェクトに委譲する
delegate :name, :title, to: :author, prefix: true
end