【Ruby】【Rails】RAILS ANTIPATTERNS、chapter3 viewのまとめ
目的
RAILS ANTIPATTERNSをのchapter3(view)の箇所を読んだのでまとめました。
- 作者: Chad Pytel,Tammer Saleh
- 出版社/メーカー: Addison-Wesley Professional
- 発売日: 2010/11/09
- メディア: Kindle版
- この商品を含むブログを見る
PHPitis(PHPっぽくなりがち)
ドメインロジックとか複雑な表示ロジックとか、全部ビュー(app/views
の下にあるファイル)に書かれがちだよねという話です。
解決策:View Helper勉強しよ!
詳しくは書かないけど、form_for
, render
, content_for
, yield(:symbol) || 'default'
, content_for?
について書かれていました。
form_for
は本当にいろいろ使えてすごいのだけど、まだまだ使い切れていない感がある。
content_for
の並びで言うと、provide
もぜひ使いたいですね。
http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-provide
解決策:いい感じにモデルにメソッド追加しよ!
以下のようなコードがあるとする。
<% if current_user && (current_user == @post.user || @post.editors.include?(current_user)) && @post.editable? && @post.user.active? %> <%= link_to 'Edit this post', edit_post_url(@post) %> <% end %>
これはモデルにメソッドを定義してあげて、view側は以下のような形にする。
<% if @post.editable_by?(current_user) %> <%= link_to 'Edit this post', edit_post_url(@post) %> <% end %>
すっきり!
メソッドを定義する場所としては、まあまあ当たり前だけどコントローラで使う場合はモデル、そうじゃなければhelperに置くと書いてあった。
そのif文、helperに移動しよ!
app/views/alerts/index.html.erb
が以下のようになっているとする。
<div class="feed"> <% if @project %> <%= link_to "Subscribe to #{@project.name} alerts.", project_alerts_url(@project, :format => :rss), :class => "feed_link" %> <% else %> <%= link_to "Subscribe to these alerts.", alerts_url(format => :rss), :class => "feed_link" %> <% end %> </div>
この場合はapp/helpers/alerts_helper.rb
を作って以下のようにメソッドを追加する。(若干仕様変わってる?)
module AlertsHelper def rss_link(project = nil) link_to("Subscribe to these #{project.name if project} alerts.", alerts_rss_url(project), class: 'feed_link') end def alerts_rss_url(project = nil) if project project_alerts_url(project, format: :rss) else alerts_url(:rss) end end end
view側のapp/views/alerts/index.html.erb
は以下。
<div class="feed"> <%= rss_link(@project) %> </div>
いつも<div class="feed">
が必要な場合は、content_tagを使ってhelperにうつしてしまってもいいとありました。
その場合はlink_to
じゃなくてcontent_tag :a
をあえて使ってもいいと書いてました。
ちょっとした感想
最後の、「helperに移動しよ!」的な話はいつも悩むところなのと、helperメソッドでcontent_tagをもりもり書くのなら、パーシャルでいいのでは?と思ったりします。
でも今回の= rss_link(@project)
が、= render rss_link, project: @project
になるのはイマイチ感がありますね…なんでだろ。
viewにかかわらず、Railsはやりたいことを色んな方法で実装することができるので、一人で作っているときでさえ統一感がなくなることが有ります。rubocopで潰せるところはいいけど、自分が統一感を持って実装出来ているかどうかたまに振り返りながらすすめていきたいですね。