本記事の内容はN+1問題を引き起こしています。
改善策はこちらの記事を参考にしてください。
目的
hogesテーブルをジャンルごとに分けて出力したい。
目標物の確認
MCVの準備
今回の目標物を実現するために最低限必要なファイルは以下です。
モデル
Hogeモデル:メインとなるhogesテーブルのモデルです。
id
カラム:データ作成と共に自動付与される値
content
カラム:表示する内容
genre_id
カラム:今回ポイントとなるカラムです。genreモデルと紐づけるためのカラムです。
Genreモデル:Hogeモデルのgenre_id
カラムと紐づけるためのモデルです。
id
カラム:データ作成と共に自動付与される値。hogeモデルのgenre_id
カラムと紐づけます。
name
カラム:genre名を設定します。
コントローラ
# アクション内で
@genres = Genre.all
ビューファイル
<% @genres.each do |genre| %>
<p><%= genre.name %></p>
<% hoges = Hoge.where(genre_id: genre.id) %>
<table>
<tr>
<td>id</td><td>content</td>
</tr>
<% hoges.each do |hoge| %>
<tr>
<td><%= hoge.id %></td>
<td><%= hoge.content %></td>
</tr>
<% end %>
</table>
<% end %>
解説
2段階で考えます。
まず、コントローラで定義した@genres
に対してeach文を回します。
<p><%= genre.name %></p>
の部分ではジャンル名を表示しています。
each文の中で、hoges
という変数を定義します。
hoges
はwhere
メソッドにより、現在each文で回っているgenreのidをgenre_idにもつ配列として定義されます。
そしてそのhoges
に対してeach文を回します。
hoges
に対するeach文が終了すると、@genres
の1周目のeachが終了します。
続いて、@genres
の2周目のeachが開始します。
これにより、hoges
テーブルのgenre_id
ごとにeach文を回すことができました。
まとめ
今回はカラムの値ごとにeach文を回す方法を紹介しました。
2段構造でeach構文を作るという少し複雑な方法ですが、ぜひ試してみてください。