renderメソッドを用いてパーシャルファイルを呼び出すときに引っかかった部分をまとめました。
通常時
class PostsController < ApplicationController
def index
@posts = Post.all
end
end
<%# posts/index.html.erb %>
<%= render @posts %>
<%# または %>
<%= render partial: 'post', collection: @posts %>
呼び出されるのは下記になります。
<%# posts/_post.html.erb %>
<%= post.id %>
コントローラーでデータを分ける場合
postデータにはcolorカラムが用意してあって2種類あるとします。
enum color: { blue: 0, red: 1}
class PostsController < ApplicationController
def index
@red_posts = Post.where(color: :red)
@blue_posts = Post.where(color: :blue)
end
end
indexで表示する場合に、分けて表示したい場合。
通常時
<%# posts/index.html.erb %>
<h1>red_post</h1>
<%= render partial: 'red_post', collection: @red_posts %>
<h1>blue_post</h1>
<%= render partial: 'blue_post', collection: @blue_posts %>
<%# posts/_red_post.html.erb %>
<%= red_post.id %>
------------------
<%# posts/_blue_post.html.erb %>
<%= blue_post.id %>
のようにできますが、今回のように呼び出す内容が同じidの場合などは、次のようにできます。
省略時
<%# posts/index.html.erb %>
<h1>red_post</h1>
<%= render @red_posts %>
<h1>blue_post</h1>
<%= render @blue_posts %>
<%# posts/_post.html.erb %>
<%= post.id %>
このようにしても、省略できます。
renderを省略形で呼び出す場合、@posts の中のモデル名(この場合は Post)に基づいてパーシャルファイルを探すからです。
おまけ
コレクションを使用する際、パーシャルファイル内の変数名は、@red_postsの単数形が常に適切であると考えがちですが、実際にはそうでない場合もあります。
<%# posts/index.html.erb %>
<h1>red_post</h1>
<%= render partial: 'red_post', collection: @red_posts %>
上記の場合は
<%# posts/_red_post.html.erb %>
<%= red_post.id %>
このようにファイルと同じ変数で問題ありませんが、
もしも、なんらかの処理があり、下記のように
<%# posts/index.html.erb %>
<h1>red_post</h1>
<%= render partial: 'red_color_post', collection: @red_posts %>
呼び出す必要があった場合はどうなるかというと、
<%# posts/_red_color_post.html.erb %>
<%= red_color_post.id %>
にする必要があります。
何故なら、collection: @red_postsは、パーシャルファイルを表示する際に、@red_posts変数を使って繰り返しレンダリングすることを指定しているだけだからです。
このとき、パーシャルファイル内で使われる変数名は、パーシャルファイル名から自動的に導出されます。
partial: 'red_color_post'こそが重要で、partialファイルの名前がred_color_postなら変数もred_color_postにする必要があるということです。
ちなみに、下記のようにした場合は
<%= render partial: 'red_color_post', collection: @red_posts, as: :red_post %>
<%# または 〜〜〜, as: "red_post"でも可 %>
<%# posts/_red_color_post.html.erb %>
<%= red_post.id %>
ファイル名と変数名が一致していなくても動きます。
まとめたグラフがこちらです。
controllerの変数名 | モデル名 | 省略? | partial | collection | パーシャルファイル名 | パーシャル内変数名 |
---|---|---|---|---|---|---|
@posts | Post | @posts | _post.html.erb | post | ||
@posts | Post | ✖️ | post | @posts | _post.html.erb | post |
@red_posts | Post | @red_posts | _post.html.erb | post | ||
@red_posts | Post | ✖️ | post | @red_posts | _post.html.erb | post |
@red_posts | Post | ✖️ | red_post | @red_posts | _red_post.html.erb | red_post |
@red_posts | Post | ✖️ | red_color_post | @red_post | _red_color_post.html.erb | red_color_post |
@posts | User | @posts | _user.html.erb | user | ||
@posts | User | ✖️ | user | @posts | _user.html.erb | user |