LoginSignup
0

More than 3 years have passed since last update.

rails/gem "ancestry"を使って多階層構造をつくる

Last updated at Posted at 2019-12-23

"ancestry"・・・ 親・子・孫みたいな多階層構造のテーブルを作れるgem。

例)食べログのラーメンカテゴリ

親   子  孫     
親:ラーメン   子1:ラーメン NULL
子2:汁なしラーメン 子2の孫: 油そば
子2の孫:台湾まぜそば
子2の孫: 汁なし担々麺
子3:つけ麺 NULL

ラーメンは3つ子要素がある。
この場合、汁なしラーメンは孫が3つある。
ラーメンとつけ麺は子のみ。

つまり、親 → 子2:”汁なしラーメン” → 孫 を作成できる。


Gemfile
 gem 'ancestry'
$ bundle install
$ rails g migration add_ancestry_to_table ancestry:string

マイグレーションファイル

category.rb
class AddAncestryToCategory < ActiveRecord::Migration[5.2]
  def change
    add_column :categories, :ancestry, :string
    add_index :categories, :ancestry
  end
end
$ rake db:migrate

 Model

category.rb
class Category < ApplicationRecord
  has_many :products_categories
  has_many :products, through: :products_categories
  has_ancestry
end

データを入れる

seeds.rb に記述するとデータを流入できます。
まずは、categoriesにデータを格納する。

db/seeds.rb
categories = [{layer1:"レディース",layer1_chaild:[
                  {layer2:"トップス",layer2_chaild:["Tシャツ/カットソー(半袖/袖なし)","Tシャツ/カットソー(七分/長袖)","シャツ/ブラウス(半袖/袖なし)","シャツ/ブラウス(七分/長袖)","ポロシャツ","キャミソール","タンクトップ","ホルターネック","ニット/セーター","チュニック","カーディガン/ボレロ)","アンサンブル","ベスト/ジレ","パーカー","トレーナー/スウェット","ベアトップ/チューブトップ","ジャージ","その他"]},
                  {layer2:"ジャケット/アウター",layer2_chaild:["テーラードジャケット","テーラードジャケット","ノーカラージャケット","Gジャン/デニムジャケット","レザージャケット","ダウンジャケット","ライダースジャケット","ミリタリージャケット","ダウンベスト","ジャンパー/ブルゾン","ポンチョ","ロングコート","トレンチコート","ダッフルコート","ピーコート","チェスターコート","モッズコート","スタジャン","毛皮/ファーコート","スプリングコート","スカジャン","その他</option></select>ノーカラージャケット","Gジャン/デニムジャケット","レザージャケット","ダウンジャケット","ライダースジャケット","ミリタリージャケット","ダウンベスト","ジャンパー/ブルゾン","ポンチョ","ロングコート","トレンチコート","ダッフルコート","ピーコート","チェスターコート","モッズコート","スタジャン","毛皮/ファーコート","スプリングコート","スカジャン","その他"]},
                  {layer2:"パンツ",layer2_chaild:["デニム/ジーンズ","ショートパンツ","カジュアルパンツ","ハーフパンツ","チノパン","ワークパンツ/カーゴパンツ","クロップドパンツ","サロペット/オーバーオール","オールインワン","サルエルパンツ","ガウチョパンツ","その他"]},
                  ]},
             {layer1:"インテリア・住まい・小物",layer1_chaild:[
                  {layer2:"キッチン/食器",layer2_chaild:["食器","調理器具","収納/キッチン雑貨","弁当用品","カトラリー(スプーン等)","テーブル用品","容器","エプロン","アルコールグッズ","浄水機","その他"]},
                  {layer2:"ベッド/マットレス",layer2_chaild:["セミシングルベッド","シングルベッド","セミダブルベッド","ダブルベッド","ワイドダブルベッド","クイーンベッド","キングベッド","脚付きマットレスベッド","マットレス","すのこベッド","ロフトベッド/システムベッド","簡易ベッド/折りたたみベッド","収納付き","その他"]},
                  ]},
             {layer1:"本・音楽・ゲーム",layer1_chaild:[
                  {layer2:"本",layer2_chaild:["文学/小説","人文/社会","ノンフィクション/教養","地図/旅行ガイド","ビジネス/経済","健康/医学","コンピュータ/IT","趣味/スポーツ/実用","住まい/暮らし/子育て","アート/エンタメ","洋書","絵本","参考書","その他"]},
                  {layer2:"漫画",layer2_chaild:["全巻セット","少年漫画","少女漫画","青年漫画","女性漫画","同人誌","その他"]},
                  {layer2:"雑誌",layer2_chaild:["アート/エンタメ/ホビー","ファッション","ニュース/総合","趣味/スポーツ","その他"]},
                  {layer2:"CD",layer2_chaild:["邦楽","洋楽","アニメ","クラシック","K-POP/アジア","キッズ/ファミリー","その他"]},
                  ]},
                ]

親要素がlayer1

{layer1:"親"

layer1_chaild:[{layer2:"子要素"                  
layer2_chaild:["孫1","孫2","孫3", ...]

categories保存する。

db/seeds.rb
categories.each do |category|
  @layer1 = Category.create(layer:"#{category[:layer1]}")  #・・・親を保存
    category[:layer1_chaild].each do |layer1_chaild|
      @layer2 = @layer1.children.create(layer:layer1_chaild[:layer2])  #・・・子を保存
        layer1_chaild[:layer2_chaild].each do |layer2_chaild|
          @layer2.children.create(layer:layer2_chaild)    #・・・孫を保存
          end
      end
    end

完成!

db/seeds.rb
categories = [{layer1:"レディース",layer1_chaild:[
                  {layer2:"トップス",layer2_chaild:["Tシャツ/カットソー(半袖/袖なし)","Tシャツ/カットソー(七分/長袖)","シャツ/ブラウス(半袖/袖なし)","シャツ/ブラウス(七分/長袖)","ポロシャツ","キャミソール","タンクトップ","ホルターネック","ニット/セーター","チュニック","カーディガン/ボレロ)","アンサンブル","ベスト/ジレ","パーカー","トレーナー/スウェット","ベアトップ/チューブトップ","ジャージ","その他"]},
                  {layer2:"ジャケット/アウター",layer2_chaild:["テーラードジャケット","テーラードジャケット","ノーカラージャケット","Gジャン/デニムジャケット","レザージャケット","ダウンジャケット","ライダースジャケット","ミリタリージャケット","ダウンベスト","ジャンパー/ブルゾン","ポンチョ","ロングコート","トレンチコート","ダッフルコート","ピーコート","チェスターコート","モッズコート","スタジャン","毛皮/ファーコート","スプリングコート","スカジャン","その他</option></select>ノーカラージャケット","Gジャン/デニムジャケット","レザージャケット","ダウンジャケット","ライダースジャケット","ミリタリージャケット","ダウンベスト","ジャンパー/ブルゾン","ポンチョ","ロングコート","トレンチコート","ダッフルコート","ピーコート","チェスターコート","モッズコート","スタジャン","毛皮/ファーコート","スプリングコート","スカジャン","その他"]},
                  {layer2:"パンツ",layer2_chaild:["デニム/ジーンズ","ショートパンツ","カジュアルパンツ","ハーフパンツ","チノパン","ワークパンツ/カーゴパンツ","クロップドパンツ","サロペット/オーバーオール","オールインワン","サルエルパンツ","ガウチョパンツ","その他"]},
                  ]},
             {layer1:"インテリア・住まい・小物",layer1_chaild:[
                  {layer2:"キッチン/食器",layer2_chaild:["食器","調理器具","収納/キッチン雑貨","弁当用品","カトラリー(スプーン等)","テーブル用品","容器","エプロン","アルコールグッズ","浄水機","その他"]},
                  {layer2:"ベッド/マットレス",layer2_chaild:["セミシングルベッド","シングルベッド","セミダブルベッド","ダブルベッド","ワイドダブルベッド","クイーンベッド","キングベッド","脚付きマットレスベッド","マットレス","すのこベッド","ロフトベッド/システムベッド","簡易ベッド/折りたたみベッド","収納付き","その他"]},
                  ]},
             {layer1:"本・音楽・ゲーム",layer1_chaild:[
                  {layer2:"本",layer2_chaild:["文学/小説","人文/社会","ノンフィクション/教養","地図/旅行ガイド","ビジネス/経済","健康/医学","コンピュータ/IT","趣味/スポーツ/実用","住まい/暮らし/子育て","アート/エンタメ","洋書","絵本","参考書","その他"]},
                  {layer2:"漫画",layer2_chaild:["全巻セット","少年漫画","少女漫画","青年漫画","女性漫画","同人誌","その他"]},
                  {layer2:"雑誌",layer2_chaild:["アート/エンタメ/ホビー","ファッション","ニュース/総合","趣味/スポーツ","その他"]},
                  {layer2:"CD",layer2_chaild:["邦楽","洋楽","アニメ","クラシック","K-POP/アジア","キッズ/ファミリー","その他"]},
                  ]},
                ]
categories.each do |category|
  @layer1 = Category.create(layer:"#{category[:layer1]}")  #・・・親を保存
    category[:layer1_chaild].each do |layer1_chaild|
      @layer2 = @layer1.children.create(layer:layer1_chaild[:layer2])  #・・・子を保存
        layer1_chaild[:layer2_chaild].each do |layer2_chaild|
          @layer2.children.create(layer:layer2_chaild)    #・・・孫を保存
          end
      end
    end

終わったら下記を打って、tableにデータがあったら成功!

$ rake db:seed

ちなみに1

孫要素がない時には一応 "layer2_chaild:[""]"と書かないと私の場合うまくいいかなかった。

ちなみに2

やっぱり、めんどくさい!孫が多ければそりゃめんどくさいです。
いい方法が思いつかなかったので教えて欲しい!
ちなみに、私は下記のように検証ツールを加工しながら作りました。
この方法も最前ではないです。めんどくさかったので。
ancestry'使用時,seedsに多階層カテゴリを書くのめんどくさいから、一気に置換してみる

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0