#はじめに
クチコミサイトを作成している中で、登録商品をカテゴリ別に表示させたいなーと思い、実装しましたのでその過程を残しておこうと思います。
ページ遷移させず表示するにはjavascriptの知識が必要ということで、今回はページ遷移させて表示させていきます。
こんな感じです。
#実装
今回の流れは以下のようになります。
①categoryモデルの作成。
②itemモデルとcategory_idを紐づける。
③アイテム一覧のページでカテゴリを選択した際に、カテゴリーコントローラーのインデックスアクションに飛ぶように設定。
④カテゴリーのインデックスアクションで、category_idに紐づいているアイテムを表示。
①categoryモデルの作成。
今回は各itemにcategoryが紐づく形にしたいので、categoryモデルを作成します。
$ rails g migration AddCategoryToItems category:reference
そして作成されたファイルに以下のように記述します。
class AddCategoryToItems < ActiveRecord::Migration[5.2]
def change
add_reference :items, :category, foreign_key: true
end
end
②itemモデルとcategory_idを紐づける。
itemモデルとcategoryモデル内にbelong_toとhas_manyを追記する。
class Item < ApplicationRecord
belongs_to :category, optional: true
end
class Category < ApplicationRecord
has_many :items
end
③アイテム一覧のページでカテゴリを選択した際に、カテゴリーコントローラーのインデックスアクションに飛ぶように設定。
次にカテゴリ別に表示したいページにてリンクを作成する。
~省略~
<div class="nav-link active"><%= link_to category.category_name, categories_path(category_id: category.id), %></div>
ここでは商品を一覧表示しているページにカテゴリリンクを作成しています。
末部をcategories_pathだけにするとパラメータが渡らないので、categories_path(category_id: category.id)
とする必要があります。
これによってURLの末尾が「categories?category_id=」となり、パラメータの値がしっかりと渡せるようになります。
④カテゴリーのインデックスアクションで、category_idに紐づいているアイテムを表示。
class CategoriesController < ApplicationController
def index
@items = Item.where(category_id: params[:category_id]).page(params[:page]).per(12).search(params[:search])
@categories = Category.all
end
end
#補足
各アイテムの登録時にcategory_idがしっかりと紐づくよう引数に注意してください。
例えば以下のようにすると上手く引数が渡りません。
~省略~
<%= f.label :category_name, "カテゴリ" %><br>
<%= f.collection_select :category_name, Category.all, :category_name, :category_name, class: "form-control", include_blank: "選択して下さい" %>
正しくは以下のようになります。
<%= f.label :category_name, "カテゴリ" %><br>
<%= f.collection_select :category_id, Category.all, :id, :category_name, class: "form-control", include_blank: "選択して下さい" %>