#decoratorとは
モデルに関係したモデルとはあまり関わりがないメソッドを入れておく場所
例えばビューでフォームに記入したフルネームを表示させたいという場合、モデルの中の名前の要素を使ってモデルとはあまり関係ないビューに表示させるためのメソッドなのでdecoratorにメソッドを書く方がいい。
モデルに直接書くのもいいが、モデルに直接関係のない働きをするメソッドなので何でもかんでもモデルに書くとモデルがパンパンになってみづらくなる。そのため「モデルから情報は取るけどメソッドの働き自体はモデルと関係ないよ」という専用の場所に書いた方が見やすくなる。その専用の場所がdecoratorというわけである。
decoratorは専用のdraperというgemを使い実装していく
draperのgemを記入
gem ‘draper’
$ bundle
draperを使えるようにする
$ rails generate draper:install
#このコマンドを使うとdecoratorを定義する場所app/decorators/application_decorator.rbが自動生成される。
Userモデルのためのdecoratorの場所を作成
$ rails generate decorator モデル名(Userなど)
#このコマンドでapp/decorators/user_decorator.rb を作成
user_decorator.rbにuserモデルを使って作りたいメソッドを作る
class UserDecorator < Draper::Decorator
delegate_all
def full_name
"#{last_name} #{first_name}"
end
end
delegate_allをつけることでUserモデルの全メソッドが使えるようになり、その結果last_nameとfirst_nameがつかえるようになった。
またuser_decorator.rb内では@userのようにインスタンス変数もつかうことができない。理由は@userはUserコントローラーで定義されたクラス、つまりコントローラーのクラスであり、一方decoratorはdecoratorクラスである。なのでそもそもクラスが違うのでインスタンス変数を使えないのである。よって”#{last_name} #{first_name}”の部分は”#{@user.last_name} #{@user.first_name}”にはできない。
full_nameというメソッドが使えるようになったのでビューで使う
<%= current_user.decorate.full_name %>
例えばこのように使う。