プログラミング学習記録

主にRuby on Railsを使ったプログラミングを学んでいます。

パーシャルでコレクションをレンダリングする/ローカル変数を渡す

パーシャルとは

部分テンプレートまたはパーシャルは、出力を扱いやすく分割するための仕組みです。パーシャルを使用することで、ビュー内のコードをいくつものファイルに分割して書き出し、他のテンプレートでも使いまわすことができます。

引用 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ガイド

Action View の概要 - Railsガイド

【Rails】 部分テンプレートの使い方を徹底解説! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト

【Rails基礎】ややこしい部分テンプレートの省略形について簡単にまとめてみた|TechTechMedia

Rails パーシャル(部分テンプレート)へローカル変数を渡したいとき - Qiita

Rails部分テンプレート(パーシャル)まとめ - Qiita

【41日目】パーシャルの中にインスタンス変数を使ってはいけない理由と正しい使い方 - Qiita

partialではインスタンス変数を参照しない方がいい - Qiita