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レイアウトで指定した「システム管理者専用ページ」というヘッダーが表示され、ヘッダーの下にユーザー独自のレイアウトが設定される。
ちなみに、adminレイアウトを指定していない他のコントローラのビューは今まで通りに表示されます。
これは色々と応用できそうです。