Rails4 レイアウトの継承

レイアウトを管理者と一般ユーザー用に分けたかった。
コントローラーを継承するのではなく、レイアウトで分ける方法を見つけたので、メモ。

app/views/layouts/application.html.erbに下記のように記載した。

<!DOCTYPE html>
<html>
  <head>
    <title>SampleProject</title>
    <%= stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true %>
    <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
    <%= csrf_meta_tags %>
  </head>
  <body>
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <div class="container">
        <div class="navbar-header">
          <button class="navbar-toggle" type="button" data-togle="collapse" data-target=".navbar-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>

          <%= link_to "SampleProject", root_path, class:  "navbar-brand" %>
        </div>

        <div class="navbar-collapse collapse">
          <% unless yield(:navbar).empty? %>
            <%= yield(:navbar) %>
          <% end %>
        </div>
      </div>
    </div>
    <div id="content">
      <%= content_for?(:content) ? yield(:content) : yield %>
    </div>
  </body>
</html>


ポイントは、contentのこの部分。
contentが指定されていたら、そちらを使い、指定されていなければ、yieldでそれぞれのビューを読み込みます。

<div id="content">
  <%= content_for?(:content) ? yield(:content) : yield %>
</div>


app/views/layouts/admin.html.erbを作成し、下記のように記載。
contentにヘッダーを追加してみました。

<% content_for :content do %>
  <h1>システム管理者専用ページ</h1>
  <%= yield %>
<% end %>
<%= render template: "layouts/application" %>


app/controllers/admin/users_controller.rbで、レイアウトに先ほど作成したadmin.html.erbを指定する。

class Admin::UsersController < ApplicationController
  layout 'admin'


すると、この管理者用のユーザー画面には、applicationレイアウトで指定したナビバーと、adminレイアウトで指定した「システム管理者専用ページ」というヘッダーが表示され、ヘッダーの下にユーザー独自のレイアウトが設定される。
f:id:ayaketan:20140212213611p:plain

ちなみに、adminレイアウトを指定していない他のコントローラのビューは今まで通りに表示されます。

これは色々と応用できそうです。


参考:
Layouts and Rendering in Rails — Ruby on Rails Guides