パーシャルでコレクションをレンダリングする/ローカル変数を渡す
パーシャルとは
部分テンプレートまたはパーシャルは、出力を扱いやすく分割するための仕組みです。パーシャルを使用することで、ビュー内のコードをいくつものファイルに分割して書き出し、他のテンプレートでも使いまわすことができます。
引用 Railsガイドより
学習する中で、重要かつこんがらがりやすい使い方や省略した書き方について記事にまとめます。
コレクションをレンダリングする
投稿一覧画面などを作る場合、各投稿の情報を投稿表示用のパーシャルへ渡し、繰り返し表示させる方法を使うと良い。
その時、繰り返し表示させるからといって
<% @posts.each do |post| %> <%= render partial: 'post', locals: { post: post } %> <% end %>
のように書くと、@postsの数だけrenderメソッドが実行されパフォーマンスが悪化する原因となる。
こういう場合は、
<%= render partial: 'post', collection: @posts %>
のようにcollection
オプションを使い、一度でレンダリングすると良い。
collection
オプションを使用するとcollection
オプションに指定した変数の要素の分だけ部分テンプレートが繰り返し表示される。
パーシャルはデータの繰り返し (コレクション) を出力する場合にもきわめて便利です。
:collection
オプションを使用してパーシャルにコレクションを渡すと、コレクションのメンバごとにパーシャルがレンダリングされて挿入されます。
引用 Railsガイドより
省略記法
また、collection
オプションを利用した書き方には以下の省略記法があり、よく使う。
<%= render @posts %>
この省略法を使うには以下の条件が必要。
- 呼び出すパーシャルがviewsフォルダ内の
posts
フォルダにある - パーシャル名が
_post.html.erb
であること - パーシャル内で使う変数が
post
であること
※各条件はpost
の場合。使用したいパーシャル名・変数名によって読み変えるべし。
ローカル変数を渡す
パーシャル内ではインスタンス変数を使うのは望ましくない。
パーシャルをレンダリングする時にローカル変数を引数として渡すとよい。
なぜパーシャル内でインスタンス変数を使うべきでないかというと、パーシャルの再利用性が低くなるため。
例えばパーシャル内でインスタンス変数を使った場合、コントローラー側でインスタンス変数に変更を加えると、パーシャル側も変更しなければならなくなる(変更しないとバグの原因になり得る)。ビューと特定のコントローラーの依存が強まり、また特定のモデルのデータに関連づけられてしまうので、別の場所で再利用できなくなる。
依存性を低くし、再利用性を高めるためローカル変数を渡す。
<%= render pertial: 'article', locals: { article: @article } %>
※localsオプションを書いている場合はpertialは省略できない
省略記法
<%= render 'article', article: @article %>
<%= render @article %>
注意
<%= render @posts %> # コレクションのレンダリング(要素の繰り返し表示)
と
<%= render @post %> # ローカル変数を渡したパーシャル
では意味と挙動が違うので注意。
参考
【Rails】 部分テンプレートの使い方を徹底解説! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト
【Rails基礎】ややこしい部分テンプレートの省略形について簡単にまとめてみた|TechTechMedia
Rails パーシャル(部分テンプレート)へローカル変数を渡したいとき - Qiita
Rails部分テンプレート(パーシャル)まとめ - Qiita