renderを使い、データベースの内容を表示する方法のメモです。
ここの例でやりたいこと:talkモデルに入っているcontentを表示する
talkモデルのcontentはブログのコメント(text形式)のようなものです。
コメント機能を実装しようとしていると考えていただければと思います。
今の状態
def index
@talks = Talk.all
end
#<table>などは省略
<% @talks.each do |talk| %>
<tr>
<td><%= talk.id %></td>
<td><%= talk.content %></td>
<td><%= talk.created_at %></td>
</tr>
<% end %>
このようにして、talkモデルのid、content、created_atを表示していました。
これをrenderで書き出す設定にしたいと思います。
部分テンプレートの作成
まず初めに、部分テンプレートを作成します。
talkモデルの表示を行いたいので "_talk.html.erb" を作成しました。
その中に、出したいhtmlを書きます。
<tr>
<td><%= talk.id %></td>
<td><%= talk.content %></td>
<td><%= talk.created_at %></td>
</tr>
そしたら、先ほどの"talks/index.html.erb"に書いてあったhtmlと<%= %>を削除。
その場所に
<%= render :partial => "talk", :collection => @talks %>
を書きます。
ここで":partial"の意味は、talks配下の部分テンプレート"_talk.html.erb"を挿入することを指定しています。
collectionにて、talkモデルのすべて(@talks = Talk.all のため)を書くことを指定しています。
このタイミングで、表示が失敗していないか確認してください。
最後に、先ほどの<%= render ....%>を
<%= render @talks %>
に書き換えておしまいです。
注意点
<%= render @talks %>を使うためにはまず、部分テンプレート名が「アンダーバー + @以下の単数形」になっている必要があります。
今回の場合では、talksの単数形はtalkなので"_talk.html.erb"としています。
次に、:collectionは@talksなどのように、モデルの複数形で指定する必要があります。
複数形にして、その中に「モデル名.all」(今回は"Talk.all")とすることで、eachを使ったときと同様に、モデルの全てのレコードを表示するまで自動で繰り返すようになります。
また、@talksのように複数形にすることで、<%= render @talks %>と書いた場合、自動的にtalksの単数形、"talk"が使われている部分テンプレートファイル「_talk.html.erb」を探しにいってくれます。
さらに、自動的に"talk"が部分テンプレートファイル内(今回の場合では"_talk.html.erb")で、@talksを順番に代入する変数として定義されるため、例えば"talk.id"などのように書くことができています。
renderで使うためのすべてのファイルは同じフォルダ(今回では"views/talks"の中)に入れる必要があり、まだフォルダ名は@以下の文字(今回では"@talks"なので"talks")と同じにする必要があります。
結論
結論としては、@talksにTalk.allが代入されている場合、<%= render @talks %>の意味は、
・部分テンプレートファイル「_talk.html.erb」をレンダリングする
・「_talk.html.erb」内の変数、"talk"に@talksの内容を一つずつ代入する
また、viewsの配下のフォルダ名がtalksで、その同じフォルダに部分テンプレとそれを使用するファイルを入れる必要がある、ということも注意点です。