はじめに
1つのコントローラーでレイアウトを使い分ける方法はいくつかあります。
今回は3つ以上使い分ける場合の方法を記事にします。
その 1.layout
メソッドとrender
メソッドの:layout
オプションを使う
コントローラー全体のレイアウトを指定したい場合はlayout
メソッドを使用します。
例えば、app/views/layouts
内のmain
レイアウトを指定する場合のコードは以下のようになります。
class UsersController < ApplicationController
layout 'main' # コントローラー内の全てのアクションにmainレイアウトを指定する
def index
end
def new
end
def show
end
def edit
end
end
また、一部のアクションにのみ指定したい場合は:except
,:only
オプションが使えます。
layout 'main', expect: :new # new以外にレイアウトを指定する
layout 'main', only: %i[show edit] # show, editにレイアウトを指定する
ただ、このlayout
メソッドは 複数記述されていると最後のlayout
メソッドのみ適応されます。
なので下記のようなコードは期待通りに動きません。
class UsersController < ApplicationController
# indexにはmainレイアウト、show,editにはsubレイアウトを指定したいけど
# 実際は
# layout 'sub', only: %i[show edit]
# しか適応されない!
layout 'main', only: :index # mainレイアウトをindexに指定
layout 'sub', only: %i[show edit] # subレイアウトはshow,editに指定
def index
end
def new
end
def show
end
def edit
end
end
この場合はrender
メソッドのlayout
オプションで、アクションごとにレイアウトを指定する方法も併用します。
render layout: 'main'
このコードも合わせた、3つ以上のレイアウトを指定するコードは下記になります。
class UsersController < ApplicationController
layout 'sub', only: %i[show edit] # show,editにsubレイアウトを指定する
def index
render layout: 'main' # indexアクションにmainレイアウトを指定する
end
def new
end
def show
end
def edit
end
end
その 2.layout
メソッドの引数にシンボルを渡す
先ほどのlayout
メソッドの引数にシンボルを渡すことで、シンボルで指定されたメソッドを呼び出せます。
class UsersController < ApplicationController
layout :switch_layout # switch_layoutメソッドを呼び出す
def index
end
def new
end
def show
end
def edit
end
private
# アクションと勘違いされないようにprivateメソッドとして定義する
def switch_layout
case action_name
when 'new' then 'main'
when 'show', 'edit' then 'sub'
end
end
end
この方法は実際にリクエストが処理されるまでレイアウトが確定しないのが特徴です。
なのでアクションに限らず、様々な条件でレイアウトを指定することができます。
まとめ
個人的にはその2の方法がシンプルで改修もやり易いと感じました。
何か直すべき点、間違った記述があればコメント等で指摘していただければと思います。
参考文献
Rails Controller で layout を複数呼び出す
https://railsguides.jp/layouts_and_rendering.html