gemのancestoryを使用した多階層構造の実装


はじめに

今回はフリマアプリでよく見かける、カテゴリの多階層構造についての実装手順を紹介していきます。

完成図

こんな感じのやつ。

やりたいこと

カテゴリを親、子、孫の三階層に分けて登録、表示する。

1.モデルの準備

今回実装したいこととして第一に商品とカテゴリを紐付けたいので、categoryとitemのモデルを作成します。

$ rails g model category 
$ rails g model item 

2.ancestoryの導入

Gemfileにancestoryを導入します。

gem 'ancestry'

ターミナルで下記コマンドを実行しよう。

$ bundle install
$ rails g migration add_ancestry_to_category ancestry:string:index
$ rails db:migrate

ancestoryを使うことで多対多の関係が1対多の関係になりDB設計がシンプルになります。
category.rbにhas_ancestoryを入れてあげましょう。

category.rb
class Category < ApplicationRecord
 has_many :items
 has_ancestry
end
item.rb
class Item < ApplicationRecord
 belongs_to :category
end

3.データの導入

seeds.rbにカテゴリのレコードを導入していきます。

seeds.rb
lady = Category.create(name: "レディース")
lady_1 = lady.children.create(name: "トップス")
lady_1.children.create([{name: "Tシャツ/カットソー(半袖/袖なし)"},{name: "Tシャツ/カットソー(七分/長袖)"},{name: "シャツ/ブラウス(半袖/袖なし)"},{name: "シャツ/ブラウス(七分/長袖)"},{name: "ポロシャツ"},{name: "キャミソール"},{name: "タンクトップ"},{name: "ホルターネック"},{name: "ニット/セーター"},{name: "チュニック"},{name: "カーディガン/ボレロ"},{name: "アンサンブル"},{name: "ベスト/ジレ"},{name: "パーカー"},{name: "トレーナー/スウェット"},{name: "ベアトップ/チューブトップ"},{name: "ジャージ"},{name: "その他"}])

ancestryを入れるとchildrenと記述することで直前の変数の子要素として扱うことができます。
細かく説明するとまず、以下の記述で親カテゴリであるレディースが登録されます。

seeds.rb
lady = Category.create(name: "レディース")

次に、以下の記述で子カテゴリであるトップスが登録されます。

seeds.rb
lady_1 = lady.children.create(name: "トップス")

そして、以下の記述で子カテゴリの孫カテゴリ群が登録されます。

seeds.rb
lady_1.children.create([{name: "Tシャツ/カットソー(半袖/袖なし)"},{name: "Tシャツ/カットソー(七分/長袖)"},{name: "シャツ/ブラウス(半袖/袖なし)"},{name: "シャツ/ブラウス(七分/長袖)"},{name: "ポロシャツ"},{name: "キャミソール"},{name: "タンクトップ"},{name: "ホルターネック"},{name: "ニット/セーター"},{name: "チュニック"},{name: "カーディガン/ボレロ"},{name: "アンサンブル"},{name: "ベスト/ジレ"},{name: "パーカー"},{name: "トレーナー/スウェット"},{name: "ベアトップ/チューブトップ"},{name: "ジャージ"},{name: "その他"}])

seeds.rb内にレコードを記述し終わったら、ターミナルで以下のコマンドを実行し、DBに反映させましょう。

$ rails db:seed

DBではこのように登録されます。

まとめ

ancestoryを使用すればアソシエーションの関係性もシンプルになるのでかなりオススメです!!!

参考記事