今日はdecoratorとhelperの違いって何だろうと思ったので調べてみました。
例えば、下のようなコードを書く場合
・他の箇所でも使うとビューが汚くなる(可読性が落ちる)
・コードを変更したいときに変更しづらい
<%= "#{@user.first_name} #{@user.last_name}" %>
などのデメリットが出てきます。
そこで下記のようなメソッドに分けるわけですが、
def full_name
end
「これはどこに定義するべきなのか?」という疑問が出てきます。
基本的にはmodelに定義で良いのですが、規模が大きくなると
それはそれで可読性が落ちたり、保守が大変になります。
そんな時にhelperとdecoratorを使っていきます。
しかし、これらはどう使い分けるのか?
結論
モデルに依存するかしないかで判断する
- helper モデルに依存しない
モデルにアクセスする際に定数が必要
module ApplicationHelper
def full_name(model)
model.first_name + model.last_name
end
end
- decorator モデルに依存する
- gemの'draper'をインストールする必要がある。
モデルにアクセスする際に定数は必要ない
decoratorを使用する場合は、記述の通りgemをインストールして、
$rails g decorator User
# user_decorater.rbを作成
すると、以下のファイルが作成されます。
(そういえば、以前decoratorのテストの書き方がいまいち分からずに苦戦した記憶が、、、)
invoke decorator
create app/decorators/user_decorator.rb
invoke test_unit
create test/decorators/user_decorator_test.rb
class UserDecorator < Draper::Decorator
delegate_all
def full_name
"#{object.last_name} #{object.first_name}"
end
end
ビューでの呼び出し方は以下の通り
<%= @user.decorate.full_name %>
毎回、decorateと書くのは面倒なので、以下のようにコントローラーに書くのもありかと。
@user = User.first.decorate
まとめ
まずはモデルにメソッドを定義することを検討する
ただ、肥大化して可読性が落ちそうな場合は、helperやdecoratorに切り分けることを検討する
- モデルに依存しないときはhelper
- モデルに依存するときはdecorator
この辺りを押さえながら書けば良さそうですね。