Templates、Partials、Layoutについて
Railsのテンプレートは様々なテンプレート形式をサポートしているらしいですが今回はおなじみの「.erb」について記載します。
「.erb」ファイルの場合、Railsでは<% %>
タグと<%= %>
タグをサポートする。
<% %>
はループやブロックを利用する際に利用し、<%= %>
は何かしらのアウトプットをしたいときに利用する。
<%= %>
を使ってみる
class ClientController < ApplicationController def index @clients.all end end
この時、@clientsにはselect * from clients
の戻り値が格納されていると思っていいです。
また、この時にindexアクションのviewに以下のように記述するとコントローラーで@clientsに格納したデータのnameカラムの一覧をViewに表示させることができる。
<ul> <li> <%= @clients.each do |client| %> <p> client.name </p> <% end %> <li> <ul>
同一Contoroller内でActionViewをRenderする
アクション名とは異なるテンプレートを表示させたい場合の例。
def update @book = Book.find(params[:id]) if @book.update(book_params) redirect_to(@book) else render "edit" end end
Updateメソッドの呼び出しに失敗した場合に、BooksControllerのeditアクションのView(edit.html.erb)ファイルを呼び出します。
別のcontrollerからActionViewを表示させる
ProductControllerのshowアクションのView(show.html.erb)を表示する
render "products/show"
rederしていることを明示的に記載したい場合は下記のようにも記述できる
render template: "products/show"
レイアウトの検索順序
Railsはレイアウトを探索する場合、最初に現在のコントローラと同じ基本名を持つレイアウトがapp/views/layoutsディレクトリにあるかどうかを調べます。たとえば、PhotosControllerクラスのアクションから出力するのであれば、app/views/layouts/photos.html.erbを探します。
該当のコントローラに属するレイアウトがない場合、app/views/layouts/application.html.erbを使用します。
コントローラーのレイアウトを指定する
プロダクトコントローラーの中でインベントリーレイアウトを指定しています。
この宣言によって、ProductsControllerからの出力で使用されるレイアウトはapp/views/layouts/inventory.html.erbになります。
class ProductsController < ApplicationController layout "inventory" #... end
アプリケーション全体で特定のレイアウトを使用する
アプリケーション全体で特定のレイアウトを使用したい場合は、ApplicationControllerクラスでlayoutを宣言する。
class ApplicationController < ActionController::Base layout "main" #... end
この宣言によって、アプリケーションのすべてのビューで使用されるレイアウトはapp/views/layouts/main.html.erbになります。
レイアウトの継承
レイアウト宣言は下の階層に継承されます。
(application_controller.rb) class ApplicationController < ActionController::Base layout "main" end
(posts_controller.rb) class PostsController < ApplicationController end
(special_posts_controller.rb) class SpecialPostsController < PostsController layout "special" end
(old_posts_controller.rb) class OldPostsController < SpecialPostsController layout false def show @post = Post.find(params[:id]) end def index @old_posts = Post.older render layout: "old" end # ... end
①ビューの出力には基本的にmainレイアウトが使用されます。
②PostsController#indexではmainレイアウトが使用されます。 (継承している)
③SpecialPostsController#indexではspecialレイアウトが使用されます。(定義している)
④OldPostsController#showではレイアウトが適用されません。 (falseを宣言している)
⑤OldPostsController#indexではoldレイアウトが使用されます。(indexアクションでoldが定義されている)
renderとredirect_toの違い
redirect_toを実行した後、コードはそこで実行を終了し、ブラウザからの次のリクエストを待ちます (通常のスタンバイ状態)。
その直後、redirect_toでブラウザに送信したHTTPステータスコード302に従って、ブラウザから別のURLへのリクエストがサーバーに送信され、サーバーはそのリクエストを改めて処理します。
Renderの場合はサーバーに対して新たなリクエストを送ることなくViewをレンダーするのでサーバブラウザ間のやり取りを減らすことができます。
部分テンプレートを利用する
(index.html.erb) <%= render "menu" %>
この場合はapp/views//_menu.html.erbを呼び出しています。
また同一フォルダ内に格納していない部分テンプレートを表示させる場合下記のように記載する。
(index.html.erb) <%= render "shared/menu" %>
この場合は下記パスのapp/views/shared/_menu.html.erbを表示させる
Partialオプション
<% @products.each do |product| %> <%= render partial: "product" , locals: {product : product}
eachメソッド内のproduct変数が部分テンプレート(_product.html.erb)内でproductという変数として利用できる
下記の場合
<% @products.each do |product| %> <%= render partial: "product" , locals: {product_partial : product} %>
eachメソッド内のproduct変数が部分テンプレート(_product.html.erb)内でproduct_partialという変数として利用できる。
以上です。