Railsでrender partialでいろいろなViewが使いまわしているViewがあるとき。ある1つのViewのときだけ見た目をちょっと変えるってことをやろうとしたときに、defined?を使うと便利かもなーというお話。
前提
users/A.html.hamlusers/B.html.hamlusers/C.html.hamlusers/D.html.hamlusers/_shared.html.haml
上のようなテンプレがあって、A~Dの中身は擬似的に書くとそれぞれこんな感じになっているとする。要はsharedをrenderしている。
-# A~D
%h1 A~C固有のタイトル
%div A~C固有の情報
= render partial: "shared"
_shared.html.hamlの中身はこんな感じで、Dのときだけは追加の情報を出したいとする。
%h1 共有部分
%div A~Dで共有
- if Dのときだけ
%div D固有の情報
対処法
renderするときに引数のようなものをlocalsによって与えられるのでそれを使うのが楽そう。というわけで、A〜CとDでその内容を変えれば分岐はうまくいきそうだ。
-# A~C
%h1 A~C固有のタイトル
%div A~C固有の情報
= render partial: "shared", locals: { show_d: false }
-# D
%h1 D固有のタイトル
%div D固有の情報
= render partial: "shared", locals: { show_d: true }
上のようにshow_dとかいう変数を使ってあげれば、条件はこのように書くことができる。
- if show_d
%div D固有の情報
もうちょっとよくする
上の方法だとDだけのためにA~C側にも変更が必要になって相当鬱陶しい。A~DのうちDだけに変更を加えて同じことを実現できるのが望ましいと思う。
やり方はA~Cにはlocalsは使わず、Dはlocals:{show_d:true}を。そして条件分岐のほうではdefined?を用いる。
- if defined? show_d
%div D固有の情報
こうすると、Dの場合はshow_dがあるので実行され、A~Cの場合はshow_dなんて変数がないからこの条件は偽になって実行されない。renderする側の変更箇所が1箇所で済むからこっちのほうが良いと思う。
でもどことなくイケてないような感じはするんだよね。もっとRailsなやり方があったら知りたい。