LoginSignup
18
16

More than 5 years have passed since last update.

Railsにおけるlayoutとその他のViewの読み込み順について

Posted at

ユーザの状態によって、Viewの表示を切り替えようとしたときに詰まってしまったのでメモ。

RailsのViewには、共通部分を司るlayoutテンプレートと、各ページ固有のコンテンツを表すテンプレートの二種類があります。各ページ固有のコンテンツであるテンプレートは、layoutの中でyieldされることで、レンダリングされます。この記事では、このテンプレートを便宜上 コンテンツテンプレート と呼ぶことにします。

今回詰まった原因は、 layoutでyieldをするかしないかによって、コンテンツテンプレートを読み込むかどうかを決められると思っていたこと です。

layout.html.erb
<!--上略-->
<%if signed_in?%>
  <%=yield%>
<%else%>
  ...
<%end%>
<!--下略-->

実際、yieldするかしないかは、プログラムがコンテンツテンプレートを読み込むかどうかということには関係ありません。なぜかというと、「プログラムが読み込んで処理した結果を表示するかしないか」を決めるのがyieldの有無だからです。yieldの有無に関わらず、プログラムはコンテンツテンプレートを読み込んで処理を行います。

参考:Railsドキュメント - yield

上記の例は、僕が今回やらかしたコードから引っ張ってきました。完全に勘違いしてますね。

通常、GETリクエストを受け取ると、Railsはルーティングに指定されたコントローラの指定されたアクションに処理を投げます。このアクションには、デフォルトで読み込むコンテンツテンプレートが設定されていて、何も設定されない場合、renderメソッドによって自動的にデフォルトのテンプレートを読み込みます。

参考:Railsドキュメント - render

いろいろ試してみたところ、RailsにおけるView処理の流れは、次のような順番になっているようです。

  1. renderメソッドを呼び出し
  2. コンテンツテンプレート読み込み&html(?)へパース
  3. レイアウトテンプレート読み込み&パースされたテンプレートをyieldで読み出し
  4. ページとしてレンダリング

おおちゃくをして、Viewレベルでのアクション切り替えもどきをしようとしたのがいけませんでした。素直にユーザの状態ごとのアクションとViewを用意して、before_filterで振り分けるようにして解決しました。

参考: Railsドキュメント - filter ,  before_filter に条件を設定する

18
16
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
18
16