概要
RailsのHelperはグローバルな名前空間を汚染するのでなるべくDraper(もしくはActiveDecorator)を使ってDecoratorパターンを使おうって話はあると思うんですが、
ここで、ちょっとしたHTMLのモジュールを表示するメソッドをDraperの中で書こうと思うと結構だるいわけですよ。
content_tag の闇
module ItemDecorator
def facebook_btn
h.content_tag(:div, class:'btn fb-btn') do
# ごちゃごちゃいろいろ書く羽目になる
end
end
end
partial を render しちゃうと楽
で、普段はslimとかで書いてて、slimのコードをcontent_tagとか使ったコードに移植してたらミスも起きやすいし、甚だ非効率だと思ったので、こういうパターンを採用してみたら、思った以上に良かったので喧伝。
module ItemDecorator
def facebook_btn
h.render '/partials/items/facebook_btn', {item: self}
end
end
.btn.fb-btn
/ いつものslim記法で書けるぞ!
これだけで随分利便性あがるなーと思ったのでした。
「これなら単にpartialをrenderすればよくないか?」への反論
これだったら、単にrenderするコードをviewの中に埋めれば一緒じゃないか、と思われるかも知れないので先に反論しつつメリットがあるのだと主張しておきます。
まず、単にrenderするコードにすると、引数に指定すべきものが多岐に渡る場合、どの引数が必要か分かりにくいという問題があり、Decoratorのメソッドを挟むことでそれが解決されます。ようは以下の例。
module ItemDecorator
def buy_btn(price, disabled=false)
h.render '/partials/items/buy_btn', {item: self, price: price, disabled: disabled}
end
end
通常のメソッドを挟んでいることで、IDEによる補完の恩恵も受けやすいです。
また、テストコードが書きやすいのもメリットです。 単に partialだけにすると、少しテストが書きにくいです(本質的には先に指摘したメソッドが切り出されているとイイネってのと同じことなのかもしれない)