o

StoneDot の Ruby on Rails 講座

LayoutとRendering

今回は View について説明していきます。 Layouts and Rendering in Rails および、 Railsドキュメント を参考にしました。

ERBの基本

HTML などに Ruby のスクリプトを埋め込むことによって出力結果を動的に変更するのが ERB です。 すべてのビューは app/view 以下のディレクトリに格納されています。

基本的なタグ

以下にコードを埋め込むために利用するタグの書き方を掲載します。

出力しない
<% ~ %>
戻り値を出力
<%= ~ %>
戻り値をエスケープしないで出力
<%== ~ %>
後ろの改行を取り除いて戻り値を出力
<% ~ -%>
行頭までの空白を削除して戻り値を出力
<%- ~ %>
コメント
<%# ~ %>

ビューの変数

ビュー内でコントローラのインスタンス変数にアクセスすることが出来ます。

@変数名

ビューの選択

デフォルトでは、コントローラは自動的にルーティングに対応したビューを使います。

例えば、 BooksController でアクション index/app/controllers/books_controllers.rb に記述してあり、ルーティングファイルに resources :booksとある場合、index が呼ばれたときは自動的に app/views/books/index.html.erbをレンダリングします。

基本的に利用されるビューは action_name.html.erb です。

ビューを明示的に指定

使用するビューを明示的に指定するためには、 render メソッドを利用します。

何もレンダリングしない場合
render :nothing => true
アクションに関連付けられたビューを使う場合
render "edit"
render :edit
render :action => "edit"

上記の例では、 edit のビューがレンダリングに使用されます。

異なるコントローラーのビューを使う場合
render "products/show"
render :templete => "products/show"

上記のようにすることで、 app/views/products/show.html.erb がテンプレートとして使われます。

全く別のビューを使う場合
render "/rails/another/app/views/products/views.html.erb"
render :file => "/rails/another/app/views/products/views.html.erb"

上記の記述ではサーバー上の /rails/another/app/views/products/views.html.erb をテンプレートとして利用します。このように絶対パスでビューを指定することも出来ます。

テキストのレンダリング

以下のように記述すると一切マークアップされていないテキストをレンダリングします。

render :text => "OK"
JSONを生成

JSONフォーマットのデータをブラウザに返したい場合は、以下のように記述します。 to_json を呼ぶ必要はありません。

render :json => @product
XMLを生成

XMLフォーマットのデータをブラウザに返したい場合は、以下のように記述します。 to_xml を呼ぶ必要はありません。

render :xml => @product
JavaScriptの生成

JavaScriptをレンダリングしたい場合は、以下のように記述します。 MIME type は自動的に埋め込まれます。

render :js => "alert('Hello Rails')"

リダイレクト

リダイレクトするには以下のように、 redirect_to に文字列でリダイレクト先を渡します。ここではヘルパーメソッドを利用しています。

redirect_to photos_url

もし、前のページに戻すためには :back を引数に指定します。

redirect_to :back

レイアウト

デフォルトではレイアウトは app/views/layouts の中のコントローラと同じ名前のものが使われます。

例えば、 PhotosController クラスの場合は app/views/layouts/photos.html.erb もしくは app/views/layouts/photos.builder が使われます。

もし、上記のようなファイルが見つからなかった場合は、 app/views/layouts/application.html.erb もしくは app/views/layouts/application.builder が使われます。

コントローラ内でのレイアウトの指定

コントローラ内で利用するレイアウトを上書きすることが出来ます。指定したレイアウト名が app/views/layouts/ ディレクトリ内から検索されます。

class ProductsController < ApplicationController
  layout "inventory"
  #...
end

上記の例では、 app/views/layouts/inventory.html.erb が利用されます。

レイアウトをrenderで指定

render メソッドにオプションとして :layout を指定することで、レイアウトを指定することが出来ます。

以下のように記述することで、 app/views/layouts/special_layout.html.erb をレイアウトとして利用することが出来ます。

render :layout => 'special_layout'

また、以下のように、 :layout => false とすることで、レイアウトを全く利用しないレンダリングを行うことが出来ます。

render :layout => false

部分テンプレート

レンダリング部分を分割して再利用性を高めるのに、部分テンプレートが便利に使えます。

部分テンプレートの名前は必ずアンダーバー(_)で始まります。

例えばビュー内で、

<%= render "menu" %>

と記述することで、 _menu.html.erb が部分テンプレートとして使われます。

以下のように記述した場合は、 app/views/shared/_menu.html.erb が部分テンプレートとして利用されます。

<%= render "shared/menu" %>

レンダリングとレイアウト

レンダリングを行う場合は現在のレイアウトとビューを組み合わせて行われます。

レイアウトでは通常のビューで利用できるタグを生成する関数、部分テンプレートに加えて、 yeild や、 content_for を利用することが出来ます。

タグ生成関数

Rails ではタグを生成するためのヘルパーが用意されています。例えば以下のようなものがあります。

yield

レイアウト内で、 yield を利用すると、その部分に現在レンダリングしようとしているビュー内容が埋め込まれます。

例えば以下のように使います。

<html>
  <head>
  </head>
  <body>
  <%= yield %>
  </body>
</html>

複数回 yield を使うことも出来ます。

<html>
  <head>
  <%= yield :head %>
  </head>
  <body>
  <%= yield %>
  </body>
</html>

yield :head のような名前付き yield の中身をレンダリングするには、 content_for メソッドを利用します。

content_for

先ほどの名前付き yield の中身をビュー側で指定するために、 content_forを利用します。

例えば、先ほどのレイアウトを使って、以下のようなビューをレンダリングすることを考えます。

<% content_for :head do %>
  <title>A simple page</title>
<% end %>
 
<p>Hello, Rails!</p>

これをレンダリングすると以下のようになります。

<html>
  <head>
  <title>A simple page</title>
  </head>
  <body>
  <p>Hello, Rails!</p>
  </body>
</html>