LoginSignup
12
10

More than 5 years have passed since last update.

Railsのlayout中の要素をページ毎に変更したい場合のプラクティス

Last updated at Posted at 2017-07-20

Rails で開発をしている際、 layout ファイル中の要素を特定のページでのみ変更したくなることがしばしばある。

例えば、次のような app/views/layouts/application.html.haml があり、ページによってサイドメニューの内容を変えたいというユースケースを考える。

%html
  %head
    -# ...
  %body
    .side-menu
      -# この部分をページによって変更したい
      = render 'side_menu'
    %main
      = yields

ダサい例: pathによる分岐

次のようにページの URL によって分離する方法をよく見かける。

- if request.path == '/'
  = render 'root_side_menu'
- else
  = render 'side_menu'

このようなやり方でしか解決できない場合もあることは認めるが、しかしクソダサい方法だと思う。

共通部分であるレイアウト側が特定部分である URL や View のことを気にしなければならない感じが嫌だし、対応しなければならない URL が増えるたびに条件式を変更しなければならないのも嫌だ。View の Template ファイル中ではこの分岐に全く触れることが出来ないのも、ロジックが分散している感じがして嫌だ。

格好いい例: content_for を使う

もっと宣言的に書こう。 yieldcontent_for を使うほうがずっといい。

まず、 layout ファイルを次のように変更しよう。

%html
  %head
    -# ...
  %body
    .side-menu
      = yield :side_menu
    %main
      = yield

次に、View の Template に content_for で表示したい内容を渡す。

-# root の view の Template
= content_for :side_menu do
  = render 'root_side_menu'
-# 他の部分の Template
= content_for :side_menu do
  = render 'side_menu'

Rails の View の yield に Symbol を渡すと、その Symbol 名を引数に持つ content_for を探して、content_for のブロックを yield の部分に差し込む。
content_for の宣言がViewファイル間で重複するのが気になる場合はHelper メソッドに逃がすなどすればいい。

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10