📘

【Rails】renderを使った部分テンプレートの呼び出し

2023/04/17に公開

部分テンプレートの作成

部分テンプレートとしてビューファイルを作成するときは、_comment.html.erbのようにファイル名の頭に_をつける必要がある。

部分テンプレートの呼び出し

1.呼び出す部分テンプレートと呼び出し元のビューファイルが同一のフォルダの場合

部分テンプレートを呼び出すにはrenderメソッドを使う必要がある。

render partial: 'ファイル名'

ファイル名は呼び出したい部分テンプレートのファイル名の_をつけずに指定する必要がある。
例えば_comment.html.erbを呼び出したいときは

render partial: 'comment'

のようにすると呼び出せる。
ちなみにpartialは省略することができ、

render 'comment'

とすることもできる。基本的には省略できる場合は省略した方がいいみたい。

2.呼び出す部分テンプレートと呼び出し元のビューファイルが別のフォルダの場合

render partial: 'フォルダ名/ファイル名'

のように部分テンプレートファイルが保存されているフォルダ名を付け加える必要がある。
例えば_comment.html.erbcommentsフォルダに保存されていたら

render partial: 'comments/comment'

のように記述する。これもpartialを省略して

render 'comments/comment'

とすることができる。

localsオプション

localsオプションを使うと呼び出した部分テンプレート内で使う変数の定義をすることができる。
例えばユーザーを登録する際のフォームを部分テンプレートとして呼び出すときなどに使う。
フォームを作るときは

_form.html.erb
<%= form_with model: @user, local: true do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
<% end %>

のように部分テンプレートを作ると@userをどこかで定義しないと使えない。ただ@user

users.controller.rb
def new
  @user = User.new
end
def create
  @user = User.new(user_params)
  @user.save
end

のようにコントローラーで記述しているのを利用したいので部分テンプレートの呼び出し時にlocalsオプションを使って部分テンプレートで使えるようにする。

<%= render partial: 'ファイル名', locals: { 部分テンプレートで使う変数: 変数に入れる値 }%>

のように使う。

new.html.erb
<%= render partial: 'form', locals: { user: @user }%>

とすると部分テンプレートの_form.html.erbを呼び出して_form.html.erbuserという変数に@userという値が入った状態で使うことができるようになる。そのため部分テンプレートの記述は

_form.html.erb
<%= form_with model: user, local: true do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
<% end %>

となる。これで_form.html.erbで``@userが使えるようになる。
localsオプションも省略することができるがlocalsを省略して記述する場合はpartialも省略しなければエラーになってしまう。

<%= render 'hoge', hoge: hoge %> => エラーは発生しない
<%= render 'hoge', locals: { hoge: hoge } %> => エラーが発生

collectionオプション

each文を使わずにデータを繰り返し表示させることができる。
ユーザー一覧画面に各ユーザの情報を表示させる際に

_user.html.erb
<%= user.name %>
<%= user.age %>

のような各ユーザーの名前と年齢を表示する部分テンプレートがあり、ユーザーの数だけ表示させるには、

index.html.erb
<% @users.each do |user| %>
  <%= render partial: 'user', locals: { user: user } %>
<% end %>

のようにcollectionオプションを使わないで記述するのはパフォーマンスが悪い。

index.html.erb
<%= render partial: 'user', collection: @users %>

のようにすると、collectionオプションに@userを渡すと、内部で要素を1つずつ取り出して部分テンプレートで処理してくれる。
collectionオプションも省略した記述がある。省略した記述を使うにはいくつか条件があり、その条件を全部満たした場合のみ省略することができる。省略した記述は

index.html.erb
<%= render @users %>

のようになる。

条件

  • 部分テンプレートが呼び出し元のファイルと同じフォルダにあること
    users/index.html.erbusers/_user.html.erbのようにディレクトリが同じである
  • 部分テンプレートのファイル名がオプションで指定した変数の単数形であること
    オプションで指定した変数が@usersだった場合ファイル名が_user.html.erbである
  • 部分テンプレート内で使用する変数名が、オプションで指定した変数の単数形であること
    オプションで@usersを渡したなら、部分テンプレート内で使用する変数名がuserである

Discussion