ユーザの状態によって、Viewの表示を切り替えようとしたときに詰まってしまったのでメモ。
RailsのViewには、共通部分を司るlayoutテンプレートと、各ページ固有のコンテンツを表すテンプレートの二種類があります。各ページ固有のコンテンツであるテンプレートは、layoutの中でyield
されることで、レンダリングされます。この記事では、このテンプレートを便宜上 コンテンツテンプレート と呼ぶことにします。
今回詰まった原因は、 layoutでyieldをするかしないかによって、コンテンツテンプレートを読み込むかどうかを決められると思っていたこと です。
<!--上略-->
<%if signed_in?%>
<%=yield%>
<%else%>
...
<%end%>
<!--下略-->
実際、yield
するかしないかは、プログラムがコンテンツテンプレートを読み込むかどうかということには関係ありません。なぜかというと、「プログラムが読み込んで処理した結果を表示するかしないか」を決めるのがyield
の有無だからです。yield
の有無に関わらず、プログラムはコンテンツテンプレートを読み込んで処理を行います。
上記の例は、僕が今回やらかしたコードから引っ張ってきました。完全に勘違いしてますね。
通常、GETリクエストを受け取ると、Railsはルーティングに指定されたコントローラの指定されたアクションに処理を投げます。このアクションには、デフォルトで読み込むコンテンツテンプレートが設定されていて、何も設定されない場合、render
メソッドによって自動的にデフォルトのテンプレートを読み込みます。
いろいろ試してみたところ、RailsにおけるView処理の流れは、次のような順番になっているようです。
-
render
メソッドを呼び出し - コンテンツテンプレート読み込み&html(?)へパース
- レイアウトテンプレート読み込み&パースされたテンプレートをyieldで読み出し
- ページとしてレンダリング
おおちゃくをして、Viewレベルでのアクション切り替えもどきをしようとしたのがいけませんでした。素直にユーザの状態ごとのアクションとViewを用意して、before_filter
で振り分けるようにして解決しました。