7
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

フリマアプリのカテゴリ機能〜gem : ancestryを使用〜

Last updated at Posted at 2020-05-01

某スクールの最終課題で初めてお目にかかるgem。それがancestry。

出品ページの情報入力の際、商品のカテゴリを階層順に選択していく部分の実装。
それがとても大変でした。同じように悩むだろう方々の助けになれば幸いです。
##完成形
Qiita#1_カテゴリ.gif

調べてみると便利!という声が多く、使いやすいらしい。

ただ、必須機能の実装にあたり、とにかく実装を完了させる必要があるため、
あくまでコードの書き方について、ここでは記載していきます。

これだけは実装前に説明すると、ancestryという単語自体の意味は、「先祖」。
意味通り、ancestryはカテゴリの階層を親・子・孫というように、
Ruby on RailsのActiveRecordモデルのレコードをツリー構造(階層)として編成することを可能にするGemです。

Mysqlに入っているデータを実際見てみると、このようになっています。
スクリーンショット 2020-04-30 10.11.57.png
・親要素:ancestryカラムが「Null」
・子要素:ancestryカラムが「親のid」
・孫要素:ancestryカラムが「親のid/子のid」
となっています。
スクリーンショット 2020-04-30 10.12.35.png
親要素がid=200のメンズになると、このようになります。
初めはこれ自体がわかりづらかったので、冒頭に記述しました。
それではここから、実装内容について記述します。

1. gemのインストール

一次ソース:https://github.com/stefankroes/ancestry

下記のように、gemfileにgemを記載して、ターミナルにてインストール。
gemを使用するテーブルにancestryカラムを追加して、migrateする。

Gemfile
gem 'ancestry'
terminal
$ bundle install
$ rails g migration add_ancestry_to_[table] ancestry:string:index
$ rails db:migrate

gemを使用するテーブル、ここではcategoryテーブルのモデルに、
「has_ancestry」を追加。

category.rb
class Category < ApplicationRecord
  has_many :items
  has_ancestry

  validates :name, presence: true
end

validationは本実装の仕様上つけることになるので、記載しています。
ここまでは、一次ソースの通り。
これで、このcategoryモデルがツリー構造になりました。
一応、商品情報のモデルと紐づいているので、そのモデルにはcategoryとのasociationを記載します。

item.rb
class Item < ApplicationRecord
 belongs_to :category
end

2. テーブルのデータ作成

本家の某フリマアプリのカテゴリを実際見てみるとわかりますが、かなり量があります。
こんなのを一つ一つテーブルに打ち込むなんて時間がかかりすぎる。。。
ということで、以下を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: "その他"}])
lady_2 = lady.children.create(name: "ジャケット/アウター")
lady_2.children.create([{name: "テーラードジャケット"},{name: "ノーカラージャケット"},{name: "Gジャン/デニムジャケット"},{name: "レザージャケット"},{name: "ダウンジャケット"},{name: "ライダースジャケット"},{name: "ミリタリージャケット"},{name: "ダウンベスト"},{name: "ジャンパー/ブルゾン"},{name: "ポンチョ"},{name: "ロングコート"},{name: "トレンチコート"},{name: "ダッフルコート"},{name: "ピーコート"},{name: "チェスターコート"},{name: "モッズコート"},{name: "スタジャン"},{name: "毛皮/ファーコート"},{name: "スプリングコート"},{name: "スカジャン"},{name: "その他"}])
lady_3 = lady.children.create(name: "パンツ")
lady_3.children.create([{name: "デニム/ジーンズ"},{name: "ショートパンツ"},{name: "カジュアルパンツ"},{name: "ハーフパンツ"},{name: "チノパン"},{name: "ワークパンツ/カーゴパンツ"},{name: "クロップドパンツ"},{name: "サロペット/オーバーオール"},{name: "オールインワン"},{name: "サルエルパンツ"},{name: "ガウチョパンツ"},{name: "その他"}])
lady_4 = lady.children.create(name: "スカート")
lady_4.children.create([{name: "ミニスカート"},{name: "ひざ丈スカート"},{name: "ロングスカート"},{name: "キュロット"},{name: "その他"}])
lady_5 = lady.children.create(name: "ワンピース")
lady_5.children.create([{name: "ミニワンピース"},{name: "ひざ丈ワンピース"},{name: "ロングワンピース"},{name: "その他"}])
lady_6 = lady.children.create(name: "靴")
lady_6.children.create([{name: "ハイヒール/パンプス"},{name: "ブーツ"},{name: "サンダル"},{name: "スニーカー"},{name: "ミュール"},{name: "モカシン"},{name: "ローファー/革靴"},{name: "フラットシューズ/バレエシューズ"},{name: "長靴/レインシューズ"},{name: "その他"}])
lady_7 = lady.children.create(name: "ルームウェア/パジャマ")
lady_7.children.create([{name: "パジャマ"},{name: "ルームウェア"}])
lady_8 = lady.children.create(name: "レッグウェア")
lady_8.children.create([{name: "ソックス"},{name: "スパッツ/レギンス"},{name: "ストッキング/タイツ"},{name: "レッグウォーマー"},{name: "その他"}])
lady_9 = lady.children.create(name: "帽子")
lady_9.children.create([{name: "ニットキャップ/ビーニー"},{name: "ハット"},{name: "ハンチング/ベレー帽"},{name: "キャップ"},{name: "キャスケット"},{name: "麦わら帽子"},{name: "その他"}])
lady_10 = lady.children.create(name: "バッグ")
lady_10.children.create([{name: "ハンドバッグ"},{name: "トートバッグ"},{name: "エコバッグ"},{name: "リュック/バックパック"},{name: "ボストンバッグ"},{name: "スポーツバッグ"},{name: "ショルダーバッグ"},{name: "クラッチバッグ"},{name: "ポーチ/バニティ"},{name: "ボディバッグ/ウェストバッグ"},{name: "マザーズバッグ"},{name: "メッセンジャーバッグ"},{name: "ビジネスバッグ"},{name: "旅行用バッグ/キャリーバッグ"},{name: "ショップ袋"},{name: "和装用バッグ"},{name: "かごバッグ"},{name: "その他"}])
lady_11 = lady.children.create(name: "アクセサリー")
lady_11.children.create([{name: "ネックレス"},{name: "ブレスレット"},{name: "バングル/リストバンド"},{name: "リング"},{name: "ピアス(片耳用)"},{name: "ピアス(両耳用)"},{name: "イヤリング"},{name: "アンクレット"},{name: "ブローチ/コサージュ"},{name: "チャーム"},{name: "その他"}])
lady_12 = lady.children.create(name: "ヘアアクセサリー")
lady_12.children.create([{name: "ヘアゴム/シュシュ"},{name: "ヘアバンド/カチューシャ"},{name: "ヘアピン"},{name: "その他"}])
lady_13 = lady.children.create(name: "小物")
lady_13.children.create([{name: "長財布"},{name: "折り財布"},{name: "コインケース/小銭入れ"},{name: "名刺入れ/定期入れ"},{name: "キーケース"},{name: "キーホルダー"},{name: "手袋/アームカバー"},{name: "ハンカチ"},{name: "ベルト"},{name: "マフラー/ショール"},{name: "ストール/スヌード"},{name: "バンダナ/スカーフ"},{name: "ネックウォーマー"},{name: "サスペンダー"},{name: "サングラス/メガネ"},{name: "モバイルケース/カバー"},{name: "手帳"},{name: "イヤマフラー"},{name: "傘"},{name: "レインコート/ポンチョ"},{name: "ミラー"},{name: "タバコグッズ"},{name: "その他"}])
lady_14 = lady.children.create(name: "時計")
lady_14.children.create([{name: "腕時計(アナログ)"},{name: "腕時計(デジタル)"},{name: "ラバーベルト"},{name: "レザーベルト"},{name: "金属ベルト"},{name: "その他"}])
lady_15 = lady.children.create(name: "ウィッグ/エクステ")
lady_15.children.create([{name: "前髪ウィッグ"},{name: "ロングストレート"},{name: "ロングカール"},{name: "ショートストレート"},{name: "ショートカール"},{name: "その他"}])
lady_16 = lady.children.create(name: "浴衣/水着")
lady_16.children.create([{name: "浴衣"},{name: "着物"},{name: "振袖"},{name: "長襦袢/半襦袢"},{name: "水着セパレート"},{name: "水着ワンピース"},{name: "水着スポーツ用"},{name: "その他"}])
lady_17 = lady.children.create(name: "スーツ/フォーマル/ドレス")
lady_17.children.create([{name: "スカートスーツ上下"},{name: "パンツスーツ上下"},{name: "ドレス"},{name: "パーティーバッグ"},{name: "シューズ"},{name: "ウェディング"},{name: "その他"}])
lady_18 = lady.children.create(name: "マタニティ")
lady_18.children.create([{name: "トップス"},{name: "アウター"},{name: "インナー"},{name: "ワンピース"},{name: "パンツ/スパッツ"},{name: "スカート"},{name: "パジャマ"},{name: "授乳服"},{name: "その他"}])
lady_19 = lady.children.create(name: "その他")
lady_19.children.create([{name: "コスプレ"},{name: "下着"},{name: "その他"}])

# メンズ
men = Category.create(name: "メンズ")
men_1 = men.children.create(name: "トップス")
men_1.children.create([{name: "Tシャツ/カットソー(半袖/袖なし)"},{name: "Tシャツ/カットソー(七分/長袖)"},{name: "シャツ"},{name: "ポロシャツ"},{name: "タンクトップ"},{name: "ニット/セーター"},{name: "パーカー"},{name: "カーディガン"},{name: "スウェット"},{name: "ジャージ"},{name: "ベスト"},{name: "その他"}])
men_2 = men.children.create(name: "ジャケット/アウター")
men_2.children.create([{name: "テーラードジャケット"},{name: "ノーカラージャケット"},{name: "Gジャン/デニムジャケット"},{name: "レザージャケット"},{name: "ダウンジャケット"},{name: "ライダースジャケット"},{name: "ミリタリージャケット"},{name: "ナイロンジャケット"},{name: "フライトジャケット"},{name: "ダッフルコート"},{name: "ピーコート"},{name: "ステンカラーコート"},{name: "トレンチコート"},{name: "モッズコート"},{name: "チェスターコート"},{name: "スタジャン"},{name: "スカジャン"},{name: "ブルゾン"},{name: "マウンテンパーカー"},{name: "ダウンベスト"},{name: "ポンチョ"},{name: "カバーオール"},{name: "その他"}])
men_3 = men.children.create(name: "パンツ")
men_3.children.create([{name: "デニム/ジーンズ"},{name: "ワークパンツ/カーゴパンツ"},{name: "スラックス"},{name: "チノパン"},{name: "ショートパンツ"},{name: "ペインターパンツ"},{name: "サルエルパンツ"},{name: "オーバーオール"},{name: "その他"}])
men_4 = men.children.create(name: "靴")
men_4.children.create([{name: "スニーカー"},{name: "サンダル"},{name: "ブーツ"},{name: "モカシン"},{name: "ドレス/ビジネス"},{name: "長靴/レインシューズ"},{name: "デッキシューズ"},{name: "その他"}])
men_5 = men.children.create(name: "バッグ")
men_5.children.create([{name: "ショルダーバッグ"},{name: "トートバッグ"},{name: "ボストンバッグ"},{name: "リュック/バックパック"},{name: "ウエストポーチ"},{name: "ボディーバッグ"},{name: "ドラムバッグ"},{name: "ビジネスバッグ"},{name: "トラベルバッグ"},{name: "メッセンジャーバッグ"},{name: "エコバッグ"},{name: "その他"}])
men_6 = men.children.create(name: "スーツ")
men_6.children.create([{name: "スーツジャケット"},{name: "スーツベスト"},{name: "スラックス"},{name: "セットアップ"},{name: "その他"}])
men_7 = men.children.create(name: "帽子")
men_7.children.create([{name: "キャップ"},{name: "ハット"},{name: "ニットキャップ/ビーニー"},{name: "ハンチング/ベレー帽"},{name: "キャスケット"},{name: "サンバイザー"},{name: "その他"}])
men_8 = men.children.create(name: "アクセサリー")
men_8.children.create([{name: "ネックレス"},{name: "ブレスレット"},{name: "バングル/リストバンド"},{name: "リング"},{name: "ピアス(片耳用)"},{name: "ピアス(両耳用)"},{name: "アンクレット"},{name: "その他"}])
men_9 = men.children.create(name: "小物")
men_9.children.create([{name: "長財布"},{name: "折り財布"},{name: "マネークリップ"},{name: "コインケース/小銭入れ"},{name: "名刺入れ/定期入れ"},{name: "キーケース"},{name: "キーホルダー"},{name: "ネクタイ"},{name: "手袋"},{name: "ハンカチ"},{name: "ベルト"},{name: "マフラー"},{name: "ストール"},{name: "バンダナ"},{name: "ネックウォーマー"},{name: "サスペンダー"},{name: "ウォレットチェーン"},{name: "サングラス/メガネ"},{name: "モバイルケース/カバー"},{name: "手帳"},{name: "ストラップ"},{name: "ネクタイピン"},{name: "カフリンクス"},{name: "イヤマフラー"},{name: "傘"},{name: "レインコート"},{name: "ミラー"},{name: "タバコグッズ"},{name: "その他"}])
men_10 = men.children.create(name: "時計")
men_10.children.create([{name: "腕時計(アナログ)"},{name: "腕時計(デジタル)"},{name: "ラバーベルト"},{name: "レザーベルト"},{name: "金属ベルト"},{name: "その他"}])
men_11 = men.children.create(name: "水着")
men_11.children.create([{name: "一般水着"},{name: "スポーツ用"},{name: "アクセサリー"},{name: "その他"}])
men_12 = men.children.create(name: "レッグウェア")
men_12.children.create([{name: "ソックス"},{name: "レギンス/スパッツ"},{name: "レッグウォーマー"},{name: "その他"}])
men_13 = men.children.create(name: "アンダーウェア")
men_13.children.create([{name: "トランクス"},{name: "ボクサーパンツ"},{name: "その他"}])
men_14 = men.children.create(name: "その他")
men_14.children.create([{name: "すべて"}])

# ベビー・キッズ
baby_kids = Category.create(name: "ベビー・キッズ")
baby_kids_1 = baby_kids.children.create(name: "ベビー服(女の子用) ~95cm")
baby_kids_1.children.create([{name: "トップス"},{name: "アウター"},{name: "パンツ"},{name: "スカート"},{name: "ワンピース"},{name: "ベビードレス"},{name: "おくるみ"},{name: "下着/肌着"},{name: "パジャマ"},{name: "ロンパース"},{name: "その他"}])
baby_kids_2 = baby_kids.children.create(name: "ベビー服(男の子用) ~95cm")
baby_kids_2.children.create([{name: "トップス"},{name: "アウター"},{name: "パンツ"},{name: "おくるみ"},{name: "下着/肌着"},{name: "パジャマ"},{name: "ロンパース"},{name: "その他"}])
baby_kids_3 = baby_kids.children.create(name: "ベビー服(男女兼用) ~95cm")
baby_kids_3.children.create([{name: "トップス"},{name: "アウター"},{name: "パンツ"},{name: "おくるみ"},{name: "下着/肌着"},{name: "パジャマ"},{name: "ロンパース"},{name: "その他"}])
baby_kids_4 = baby_kids.children.create(name: "キッズ服(女の子用) 100cm~")
baby_kids_4.children.create([{name: "コート"},{name: "ジャケット/上着"},{name: "トップス(Tシャツ/カットソー)"},{name: "トップス(トレーナー)"},{name: "トップス(チュニック)"},{name: "トップス(タンクトップ)"},{name: "トップス(その他)"},{name: "スカート"},{name: "パンツ"},{name: "ワンピース"},{name: "セットアップ"},{name: "パジャマ"},{name: "フォーマル/ドレス"},{name: "和服"},{name: "浴衣"},{name: "甚平"},{name: "水着"},{name: "その他"}])
baby_kids_5 = baby_kids.children.create(name: "キッズ服(男の子用) 100cm~")
baby_kids_5.children.create([{name: "コート"},{name: "ジャケット/上着"},{name: "トップス(Tシャツ/カットソー)"},{name: "トップス(トレーナー)"},{name: "トップス(その他)"},{name: "パンツ"},{name: "セットアップ"},{name: "パジャマ"},{name: "フォーマル/ドレス"},{name: "和服"},{name: "浴衣"},{name: "甚平"},{name: "水着"},{name: "その他"}])
baby_kids_6 = baby_kids.children.create(name: "キッズ服(男女兼用) 100cm~")
baby_kids_6.children.create([{name: "コート"},{name: "ジャケット/上着"},{name: "トップス(Tシャツ/カットソー)"},{name: "トップス(トレーナー)"},{name: "トップス(その他)"},{name: "ボトムス"},{name: "パジャマ"},{name: "その他"}])
baby_kids_7 = baby_kids.children.create(name: "キッズ靴")
baby_kids_7.children.create([{name: "スニーカー"},{name: "サンダル"},{name: "ブーツ"},{name: "長靴"},{name: "その他"}])
baby_kids_8 = baby_kids.children.create(name: "子ども用ファッション小物")
baby_kids_8.children.create([{name: "靴下/スパッツ"},{name: "帽子"},{name: "エプロン"},{name: "サスペンダー"},{name: "タイツ"},{name: "ハンカチ"},{name: "バンダナ"},{name: "ベルト"},{name: "マフラー"},{name: "傘"},{name: "手袋"},{name: "スタイ"},{name: "バッグ"},{name: "その他"}])
baby_kids_9 = baby_kids.children.create(name: "おむつ/トイレ/バス")
baby_kids_9.children.create([{name: "おむつ用品"},{name: "おまる/補助便座"},{name: "トレーニングパンツ"},{name: "ベビーバス"},{name: "お風呂用品"},{name: "その他"}])
baby_kids_10 = baby_kids.children.create(name: "外出/移動用品")
baby_kids_10.children.create([{name: "ベビーカー"},{name: "抱っこひも/スリング"},{name: "チャイルドシート"},{name: "その他"}])
baby_kids_11 = baby_kids.children.create(name: "授乳/食事")
baby_kids_11.children.create([{name: "ミルク"},{name: "ベビーフード"},{name: "ベビー用食器"},{name: "その他"}])
baby_kids_12 = baby_kids.children.create(name: "ベビー家具/寝具/室内用品")
baby_kids_12.children.create([{name: "ベッド"},{name: "布団/毛布"},{name: "イス"},{name: "たんす"},{name: "その他"}])
baby_kids_13 = baby_kids.children.create(name: "おもちゃ")
baby_kids_13.children.create([{name: "おふろのおもちゃ"},{name: "がらがら"},{name: "オルゴール"},{name: "ベビージム"},{name: "手押し車/カタカタ"},{name: "知育玩具"},{name: "その他"}])
baby_kids_14 = baby_kids.children.create(name: "行事/記念品")
baby_kids_14.children.create([{name: "お宮参り用品"},{name: "お食い初め用品"},{name: "アルバム"},{name: "手形/足形"},{name: "その他"}])
baby_kids_15 = baby_kids.children.create(name: "その他")
baby_kids_15.children.create([{name: "母子手帳用品"},{name: "その他"}])

# インテリア・住まい・小物
interior_residence_accessory = Category.create(name: "インテリア・住まい・小物")
interior_residence_accessory_1 = interior_residence_accessory.children.create(name: "キッチン/食器")
interior_residence_accessory_1.children.create([{name: "食器"},{name: "調理器具"},{name: "収納/キッチン雑貨"},{name: "弁当用品"},{name: "カトラリー(スプーン等)"},{name: "テーブル用品"},{name: "容器"},{name: "エプロン"},{name: "アルコールグッズ"},{name: "浄水機"},{name: "その他"}])
interior_residence_accessory_2 = interior_residence_accessory.children.create(name: "ベッド/マットレス")
interior_residence_accessory_2.children.create([{name: "セミシングルベッド"},{name: "シングルベッド"},{name: "セミダブルベッド"},{name: "ダブルベッド"},{name: "ワイドダブルベッド"},{name: "クイーンベッド"},{name: "キングベッド"},{name: "脚付きマットレスベッド"},{name: "マットレス"},{name: "すのこベッド"},{name: "ロフトベッド/システムベッド"},{name: "簡易ベッド/折りたたみベッド"},{name: "収納付き"},{name: "その他"}])
interior_residence_accessory_3 = interior_residence_accessory.children.create(name: "ソファ/ソファベッド")
interior_residence_accessory_3.children.create([{name: "ソファセット"},{name: "シングルソファ"},{name: "ラブソファ"},{name: "トリプルソファ"},{name: "オットマン"},{name: "コーナーソファ"},{name: "ビーズソファ/クッションソファ"},{name: "ローソファ/フロアソファ"},{name: "ソファベッド"},{name: "応接セット"},{name: "ソファカバー"},{name: "リクライニングソファ"},{name: "その他"}])
interior_residence_accessory_4 = interior_residence_accessory.children.create(name: "椅子/チェア")
interior_residence_accessory_4.children.create([{name: "一般"},{name: "スツール"},{name: "ダイニングチェア"},{name: "ハイバックチェア"},{name: "ロッキングチェア"},{name: "座椅子"},{name: "折り畳みイス"},{name: "デスクチェア"},{name: "その他"}])
interior_residence_accessory_5 = interior_residence_accessory.children.create(name: "机/テーブル")
interior_residence_accessory_5.children.create([{name: "こたつ"},{name: "カウンターテーブル"},{name: "サイドテーブル"},{name: "センターテーブル"},{name: "ダイニングテーブル"},{name: "座卓/ちゃぶ台"},{name: "アウトドア用"},{name: "パソコン用"},{name: "事務机/学習机"},{name: "その他"}])
interior_residence_accessory_6 = interior_residence_accessory.children.create(name: "収納家具")
interior_residence_accessory_6.children.create([{name: "リビング収納"},{name: "キッチン収納"},{name: "玄関/屋外収納"},{name: "バス/トイレ収納"},{name: "本収納"},{name: "本/CD/DVD収納"},{name: "洋服タンス/押入れ収納"},{name: "電話台/ファックス台"},{name: "ドレッサー/鏡台"},{name: "棚/ラック"},{name: "ケース/ボックス"},{name: "その他"}])
interior_residence_accessory_7 = interior_residence_accessory.children.create(name: "ラグ/カーペット/マット")
interior_residence_accessory_7.children.create([{name: "ラグ"},{name: "カーペット"},{name: "ホットカーペット"},{name: "玄関/キッチンマット"},{name: "トイレ/バスマット"},{name: "その他"}])
interior_residence_accessory_8 = interior_residence_accessory.children.create(name: "カーテン/ブラインド")
interior_residence_accessory_8.children.create([{name: "カーテン"},{name: "ブラインド"},{name: "ロールスクリーン"},{name: "のれん"},{name: "その他"}])
interior_residence_accessory_9 = interior_residence_accessory.children.create(name: "ライト/照明")
interior_residence_accessory_9.children.create([{name: "蛍光灯/電球"},{name: "天井照明"},{name: "フロアスタンド"},{name: "その他"}])
interior_residence_accessory_10 = interior_residence_accessory.children.create(name: "寝具")
interior_residence_accessory_10.children.create([{name: "布団/毛布"},{name: "枕"},{name: "シーツ/カバー"},{name: "その他"}])
interior_residence_accessory_11 = interior_residence_accessory.children.create(name: "インテリア小物")
interior_residence_accessory_11.children.create([{name: "ごみ箱"},{name: "ウェルカムボード"},{name: "オルゴール"},{name: "クッション"},{name: "クッションカバー"},{name: "スリッパラック"},{name: "ティッシュボックス"},{name: "バスケット/かご"},{name: "フォトフレーム"},{name: "マガジンラック"},{name: "モビール"},{name: "モビール"},{name: "花瓶"},{name: "灰皿"},{name: "傘立て"},{name: "小物入れ"},{name: "置時計"},{name: "掛時計/柱時計"},{name: "鏡(立て掛け式)"},{name: "鏡(壁掛け式)"},{name: "置物"},{name: "風鈴"},{name: "植物/観葉植物"},{name: "その他"}])
interior_residence_accessory_12 = interior_residence_accessory.children.create(name: "季節/年中行事")
interior_residence_accessory_12.children.create([{name: "正月"},{name: "成人式"},{name: "バレンタインデー"},{name: "ひな祭り"},{name: "子どもの日"},{name: "母の日"},{name: "父の日"},{name: "父の日"},{name: "サマーギフト/お中元"},{name: "夏/夏休み"},{name: "ハロウィン"},{name: "敬老の日"},{name: "七五三"},{name: "お歳暮"},{name: "クリスマス"},{name: "冬一般"},{name: "その他"}])
interior_residence_accessory_13 = interior_residence_accessory.children.create(name: "その他")
interior_residence_accessory_13.children.create([{name: "すべて"}])

# 本・音楽・ゲーム
book_music_game = Category.create(name: "本・音楽・ゲーム")
book_music_game_1 = book_music_game.children.create(name: "本")
book_music_game_1.children.create([{name: "文学/小説"},{name: "人文/社会"},{name: "ノンフィクション/教養"},{name: "地図/旅行ガイド"},{name: "ビジネス/経済"},{name: "ビジネス/経済"},{name: "健康/医学"},{name: "コンピュータ/IT"},{name: "趣味/スポーツ/実用"},{name: "住まい/暮らし/子育て"},{name: "アート/エンタメ"},{name: "洋書"},{name: "絵本"},{name: "参考書"},{name: "その他"}])
book_music_game_2 = book_music_game.children.create(name: "漫画")
book_music_game_2.children.create([{name: "全巻セット"},{name: "少年漫画"},{name: "少女漫画"},{name: "青年漫画"},{name: "女性漫画"},{name: "同人誌"},{name: "その他"}])
book_music_game_3 = book_music_game.children.create(name: "雑誌")
book_music_game_3.children.create([{name: "アート/エンタメ/ホビー"},{name: "ファッション"},{name: "ニュース/総合"},{name: "趣味/スポーツ"},{name: "その他"}])
book_music_game_4 = book_music_game.children.create(name: "CD")
book_music_game_4.children.create([{name: "邦楽"},{name: "洋楽"},{name: "アニメ"},{name: "クラシック"},{name: "K-POP/アジア"},{name: "キッズ/ファミリー"},{name: "その他"}])
book_music_game_5 = book_music_game.children.create(name: "DVD/ブルーレイ")
book_music_game_5.children.create([{name: "外国映画"},{name: "日本映画"},{name: "アニメ"},{name: "TVドラマ"},{name: "ミュージック"},{name: "お笑い/バラエティ"},{name: "スポーツ/フィットネス"},{name: "キッズ/ファミリー"},{name: "その他"}])
book_music_game_6 = book_music_game.children.create(name: "レコード")
book_music_game_6.children.create([{name: "邦楽"},{name: "洋楽"},{name: "その他"}])
book_music_game_7 = book_music_game.children.create(name: "テレビゲーム")
book_music_game_7.children.create([{name: "家庭用ゲーム本体"},{name: "家庭用ゲームソフト"},{name: "携帯用ゲーム本体"},{name: "携帯用ゲームソフト"},{name: "PCゲーム"},{name: "その他"}])

# おもちゃ・ホビー・グッズ
toy_hobby_goods = Category.create(name: "おもちゃ・ホビー・グッズ")
toy_hobby_goods_1 = toy_hobby_goods.children.create(name: "おもちゃ")
toy_hobby_goods_1.children.create([{name: "キャラクターグッズ"},{name: "ぬいぐるみ"},{name: "小物/アクセサリー"},{name: "模型/プラモデル"},{name: "ミニカー"},{name: "トイラジコン"},{name: "プラモデル"},{name: "ホビーラジコン"},{name: "鉄道模型"},{name: "その他"}])
toy_hobby_goods_2 = toy_hobby_goods.children.create(name: "タレントグッズ")
toy_hobby_goods_2.children.create([{name: "アイドル"},{name: "ミュージシャン"},{name: "タレント/お笑い芸人"},{name: "スポーツ選手"},{name: "その他"}])
toy_hobby_goods_3 = toy_hobby_goods.children.create(name: "コミック/アニメグッズ")
toy_hobby_goods_3.children.create([{name: "ストラップ"},{name: "キーホルダー"},{name: "バッジ"},{name: "カード"},{name: "クリアファイル"},{name: "ポスター"},{name: "タオル"},{name: "その他"}])
toy_hobby_goods_4 = toy_hobby_goods.children.create(name: "トレーディングカード")
toy_hobby_goods_4.children.create([{name: "遊戯王"},{name: "マジック:ザ・ギャザリング"},{name: "ポケモンカードゲーム"},{name: "デュエルマスターズ"},{name: "バトルスピリッツ"},{name: "プリパラ"},{name: "アイカツ"},{name: "カードファイト!! ヴァンガード"},{name: "ヴァイスシュヴァルツ"},{name: "プロ野球オーナーズリーグ"},{name: "ベースボールヒーローズ"},{name: "ドラゴンボール"},{name: "スリーブ"},{name: "その他"}])
toy_hobby_goods_5 = toy_hobby_goods.children.create(name: "フィギュア")
toy_hobby_goods_5.children.create([{name: "コミック/アニメ"},{name: "特撮"},{name: "ゲームキャラクター"},{name: "SF/ファンタジー/ホラー"},{name: "アメコミ"},{name: "スポーツ"},{name: "ミリタリー"},{name: "その他"}])
toy_hobby_goods_6 = toy_hobby_goods.children.create(name: "楽器/器材")
toy_hobby_goods_6.children.create([{name: "エレキギター"},{name: "アコースティックギター"},{name: "ベース"},{name: "エフェクター"},{name: "アンプ"},{name: "弦楽器"},{name: "管楽器"},{name: "鍵盤楽器"},{name: "打楽器"},{name: "和楽器"},{name: "楽譜/スコア"},{name: "レコーディング/PA機器"},{name: "DJ機器"},{name: "DTM/DAW"},{name: "その他"}])
toy_hobby_goods_7 = toy_hobby_goods.children.create(name: "コレクション")
toy_hobby_goods_7.children.create([{name: "武具"},{name: "使用済切手/官製はがき"},{name: "旧貨幣/金貨/銀貨/記念硬貨"},{name: "印刷物"},{name: "ノベルティグッズ"},{name: "その他"}])
toy_hobby_goods_8 = toy_hobby_goods.children.create(name: "ミリタリー")
toy_hobby_goods_8.children.create([{name: "トイガン"},{name: "個人装備"},{name: "その他"}])
toy_hobby_goods_9 = toy_hobby_goods.children.create(name: "美術品")
toy_hobby_goods_9.children.create([{name: "陶芸"},{name: "ガラス"},{name: "漆芸"},{name: "金属工芸"},{name: "絵画/タペストリ"},{name: "版画"},{name: "彫刻/オブジェクト"},{name: "書"},{name: "写真"},{name: "その他"}])
toy_hobby_goods_10 = toy_hobby_goods.children.create(name: "アート用品")
toy_hobby_goods_10.children.create([{name: "画材"},{name: "額縁"},{name: "その他"}])
toy_hobby_goods_11 = toy_hobby_goods.children.create(name: "その他")
toy_hobby_goods_11.children.create([{name: "トランプ/UNO"},{name: "カルタ/百人一首"},{name: "ダーツ"},{name: "ビリヤード"},{name: "麻雀"},{name: "パズル/ジグソーパズル"},{name: "囲碁/将棋"},{name: "オセロ/チェス"},{name: "人生ゲーム"},{name: "野球/サッカーゲーム"},{name: "スポーツ"},{name: "三輪車/乗り物"},{name: "ヨーヨー"},{name: "模型製作用品"},{name: "鉄道"},{name: "航空機"},{name: "アマチュア無線"},{name: "パチンコ/パチスロ"},{name: "その他"}])

# コスメ・香水・美容
cosme_perfume_beauty = Category.create(name: "コスメ・香水・美容")
cosme_perfume_beauty_1 = cosme_perfume_beauty.children.create(name: "ベースメイク")
cosme_perfume_beauty_1.children.create([{name: "ファンデーション"},{name: "化粧下地"},{name: "コントロールカラー"},{name: "BBクリーム"},{name: "CCクリーム"},{name: "コンシーラー"},{name: "フェイスパウダー"},{name: "トライアルセット/サンプル"},{name: "その他"}])
cosme_perfume_beauty_2 = cosme_perfume_beauty.children.create(name: "メイクアップ")
cosme_perfume_beauty_2.children.create([{name: "アイシャドウ"},{name: "口紅"},{name: "リップグロス"},{name: "リップライナー"},{name: "チーク"},{name: "フェイスカラー"},{name: "マスカラ"},{name: "アイライナー"},{name: "つけまつげ"},{name: "アイブロウペンシル"},{name: "パウダーアイブロウ"},{name: "眉マスカラ"},{name: "トライアルセット/サンプル"},{name: "メイク道具/化粧小物"},{name: "美顔用品/美顔ローラー"},{name: "その他"}])
cosme_perfume_beauty_3 = cosme_perfume_beauty.children.create(name: "ネイルケア")
cosme_perfume_beauty_3.children.create([{name: "ネイルカラー"},{name: "カラージェル"},{name: "ネイルベースコート/トップコート"},{name: "ネイルアート用品"},{name: "ネイルパーツ"},{name: "ネイルチップ/付け爪"},{name: "手入れ用具"},{name: "除光液"},{name: "その他"}])
cosme_perfume_beauty_4 = cosme_perfume_beauty.children.create(name: "香水")
cosme_perfume_beauty_4.children.create([{name: "香水(女性用)"},{name: "香水(男性用)"},{name: "ユニセックス"},{name: "ボディミスト"},{name: "その他"}])
cosme_perfume_beauty_5 = cosme_perfume_beauty.children.create(name: "スキンケア/基礎化粧品")
cosme_perfume_beauty_5.children.create([{name: "化粧水/ローション"},{name: "乳液/ミルク"},{name: "美容液"},{name: "フェイスクリーム"},{name: "洗顔料"},{name: "クレンジング/メイク落とし"},{name: "パック/フェイスマスク"},{name: "ジェル/ゲル"},{name: "ブースター/導入液"},{name: "アイケア"},{name: "リップケア"},{name: "トライアルセット/サンプル"},{name: "洗顔グッズ"},{name: "その他"}])
cosme_perfume_beauty_6 = cosme_perfume_beauty.children.create(name: "ヘアケア")
cosme_perfume_beauty_6.children.create([{name: "シャンプー"},{name: "トリートメント"},{name: "コンディショナー"},{name: "リンス"},{name: "スタイリング剤"},{name: "カラーリング剤"},{name: "ブラシ"},{name: "その他"}])
cosme_perfume_beauty_7 = cosme_perfume_beauty.children.create(name: "ボディケア")
cosme_perfume_beauty_7.children.create([{name: "オイル/クリーム"},{name: "ハンドクリーム"},{name: "ローション"},{name: "日焼け止め/サンオイル"},{name: "ボディソープ"},{name: "入浴剤"},{name: "制汗/デオドラント"},{name: "フットケア"},{name: "その他"}])
cosme_perfume_beauty_8 = cosme_perfume_beauty.children.create(name: "オーラルケア")
cosme_perfume_beauty_8.children.create([{name: "口臭防止/エチケット用品"},{name: "歯ブラシ"},{name: "その他"}])
cosme_perfume_beauty_9 = cosme_perfume_beauty.children.create(name: "リラクゼーション")
cosme_perfume_beauty_9.children.create([{name: "エッセンシャルオイル"},{name: "芳香器"},{name: "お香/香炉"},{name: "キャンドル"},{name: "リラクゼーショングッズ"},{name: "その他"}])
cosme_perfume_beauty_10 = cosme_perfume_beauty.children.create(name: "ダイエット")
cosme_perfume_beauty_10.children.create([{name: "ダイエット食品"},{name: "エクササイズ用品"},{name: "体重計"},{name: "体脂肪計"},{name: "その他"}])
cosme_perfume_beauty_11 = cosme_perfume_beauty.children.create(name: "その他")
cosme_perfume_beauty_11.children.create([{name: "健康用品"},{name: "看護/介護用品"},{name: "救急/衛生用品"},{name: "その他"}])

# 家電・スマホ・カメラ
appliance_smartphone_camera = Category.create(name: "家電・スマホ・カメラ")
appliance_smartphone_camera_1 = appliance_smartphone_camera.children.create(name: "スマートフォン/携帯電話")
appliance_smartphone_camera_1.children.create([{name: "スマートフォン本体"},{name: "バッテリー/充電器"},{name: "携帯電話本体"},{name: "PHS本体"},{name: "その他"}])
appliance_smartphone_camera_2 = appliance_smartphone_camera.children.create(name: "スマホアクセサリー")
appliance_smartphone_camera_2.children.create([{name: "Android用ケース"},{name: "iPhone用ケース"},{name: "カバー"},{name: "イヤホンジャック"},{name: "ストラップ"},{name: "フィルム"},{name: "自撮り棒"},{name: "その他"}])
appliance_smartphone_camera_3 = appliance_smartphone_camera.children.create(name: "PC/タブレット")
appliance_smartphone_camera_3.children.create([{name: "タブレット"},{name: "ノートPC"},{name: "デスクトップ型PC"},{name: "ディスプレイ"},{name: "電子ブックリーダー"},{name: "PC周辺機器"},{name: "PCパーツ"},{name: "その他"}])
appliance_smartphone_camera_4 = appliance_smartphone_camera.children.create(name: "カメラ")
appliance_smartphone_camera_4.children.create([{name: "デジタルカメラ"},{name: "ビデオカメラ"},{name: "レンズ(単焦点)"},{name: "レンズ(ズーム)"},{name: "フィルムカメラ"},{name: "防犯カメラ"},{name: "その他"}])
appliance_smartphone_camera_5 = appliance_smartphone_camera.children.create(name: "テレビ/映像機器")
appliance_smartphone_camera_5.children.create([{name: "テレビ"},{name: "プロジェクター"},{name: "ブルーレイレコーダー"},{name: "DVDレコーダー"},{name: "ブルーレイプレーヤー"},{name: "DVDプレーヤー"},{name: "映像用ケーブル"},{name: "その他"}])
appliance_smartphone_camera_6 = appliance_smartphone_camera.children.create(name: "オーディオ機器")
appliance_smartphone_camera_6.children.create([{name: "ポータブルプレーヤー"},{name: "イヤフォン"},{name: "ヘッドフォン"},{name: "アンプ"},{name: "スピーカー"},{name: "ケーブル/シールド"},{name: "ラジオ"},{name: "その他"}])
appliance_smartphone_camera_7 = appliance_smartphone_camera.children.create(name: "美容/健康")
appliance_smartphone_camera_7.children.create([{name: "ヘアドライヤー"},{name: "ヘアアイロン"},{name: "美容機器"},{name: "電気シェーバー"},{name: "電動歯ブラシ"},{name: "その他"}])
appliance_smartphone_camera_8 = appliance_smartphone_camera.children.create(name: "冷暖房/空調")
appliance_smartphone_camera_8.children.create([{name: "エアコン"},{name: "空気清浄器"},{name: "加湿器"},{name: "扇風機"},{name: "除湿機"},{name: "ファンヒーター"},{name: "電気ヒーター"},{name: "オイルヒーター"},{name: "ストーブ"},{name: "ホットカーペット"},{name: "こたつ"},{name: "電気毛布"},{name: "その他"}])
appliance_smartphone_camera_9 = appliance_smartphone_camera.children.create(name: "生活家電")
appliance_smartphone_camera_9.children.create([{name: "冷蔵庫"},{name: "洗濯機"},{name: "炊飯器"},{name: "電子レンジ/オーブン"},{name: "調理機器"},{name: "アイロン"},{name: "掃除機"},{name: "エスプレッソマシン"},{name: "コーヒーメーカー"},{name: "衣類乾燥機"},{name: "その他"}])
appliance_smartphone_camera_10 = appliance_smartphone_camera.children.create(name: "その他")
appliance_smartphone_camera_10.children.create([{name: "その他"}])
# スポーツ・レジャー
sport_leisure = Category.create(name: "スポーツ・レジャー")
sport_leisure_1 = sport_leisure.children.create(name: "ゴルフ")
sport_leisure_1.children.create([{name: "クラブ"},{name: "ウエア(男性用)"},{name: "ウエア(女性用)"},{name: "バッグ"},{name: "シューズ(男性用)"},{name: "シューズ(女性用)"},{name: "アクセサリー"},{name: "その他"}])
sport_leisure_2 = sport_leisure.children.create(name: "フィッシング")
sport_leisure_2.children.create([{name: "ロッド"},{name: "リール"},{name: "ルアー用品"},{name: "ウエア"},{name: "釣り糸/ライン"},{name: "その他"}])
sport_leisure_3 = sport_leisure.children.create(name: "自転車")
sport_leisure_3.children.create([{name: "自転車本体"},{name: "ウエア"},{name: "パーツ"},{name: "アクセサリー"},{name: "バッグ"},{name: "工具/メンテナンス"},{name: "その他"}])
sport_leisure_4 = sport_leisure.children.create(name: "トレーニング/エクササイズ")
sport_leisure_4.children.create([{name: "ランニング"},{name: "ウォーキング"},{name: "ヨガ"},{name: "トレーニング用品"},{name: "その他"}])
sport_leisure_5 = sport_leisure.children.create(name: "野球")
sport_leisure_5.children.create([{name: "ウェア"},{name: "シューズ"},{name: "グローブ"},{name: "バット"},{name: "アクセサリー"},{name: "防具"},{name: "練習機器"},{name: "記念グッズ"},{name: "応援グッズ"},{name: "その他"}])
sport_leisure_6 = sport_leisure.children.create(name: "サッカー/フットサル")
sport_leisure_6.children.create([{name: "ウェア"},{name: "シューズ"},{name: "ボール"},{name: "アクセサリー"},{name: "記念グッズ"},{name: "応援グッズ"},{name: "その他"}])
sport_leisure_7 = sport_leisure.children.create(name: "テニス")
sport_leisure_7.children.create([{name: "ラケット(硬式用)"},{name: "ラケット(軟式用)"},{name: "ウェア"},{name: "シューズ"},{name: "ボール"},{name: "アクセサリー"},{name: "記念グッズ"},{name: "応援グッズ"},{name: "その他"}])
sport_leisure_8 = sport_leisure.children.create(name: "スノーボード")
sport_leisure_8.children.create([{name: "ボード"},{name: "バインディング"},{name: "ブーツ(男性用)"},{name: "ブーツ(女性用)"},{name: "ブーツ(子ども用)"},{name: "ウエア/装備(男性用)"},{name: "ウエア/装備(女性用)"},{name: "ウエア/装備(子ども用)"},{name: "アクセサリー"},{name: "バッグ"},{name: "その他"}])
sport_leisure_9 = sport_leisure.children.create(name: "スキー")
sport_leisure_9.children.create([{name: "板"},{name: "ブーツ(男性用)"},{name: "ブーツ(女性用)"},{name: "ブーツ(子ども用)"},{name: "ビンディング"},{name: "ウエア(男性用)"},{name: "ウエア(女性用)"},{name: "ウエア(子ども用)"},{name: "ストック"},{name: "その他"}])
sport_leisure_10 = sport_leisure.children.create(name: "その他スポーツ")
sport_leisure_10.children.create([{name: "ダンス/バレエ"},{name: "サーフィン"},{name: "バスケットボール"},{name: "バドミントン"},{name: "バレーボール"},{name: "スケートボード"},{name: "陸上競技"},{name: "ラグビー"},{name: "アメリカンフットボール"},{name: "ボクシング"},{name: "ボウリング"},{name: "その他"}])
sport_leisure_11 = sport_leisure.children.create(name: "アウトドア")
sport_leisure_11.children.create([{name: "テント/タープ"},{name: "ライト/ランタン"},{name: "寝袋/寝具"},{name: "テーブル/チェア"},{name: "ストーブ/コンロ"},{name: "調理器具"},{name: "食器"},{name: "登山用品"},{name: "その他"}])
sport_leisure_12 = sport_leisure.children.create(name: "その他")
sport_leisure_12.children.create([{name: "旅行用品"},{name: "その他"}])

# ハンドメイド
handmade = Category.create(name: "ハンドメイド")
handmade_1 = handmade.children.create(name: "アクセサリー(女性用)")
handmade_1.children.create([{name: "ピアス"},{name: "イヤリング"},{name: "ネックレス"},{name: "ブレスレット"},{name: "リング"},{name: "チャーム"},{name: "ヘアゴム"},{name: "アンクレット"},{name: "その他"}])
handmade_2 = handmade.children.create(name: "ファッション/小物")
handmade_2.children.create([{name: "バッグ(女性用)"},{name: "バッグ(男性用)"},{name: "財布(女性用)"},{name: "財布(男性用)"},{name: "ファッション雑貨"},{name: "その他"}])
handmade_3 = handmade.children.create(name: "アクセサリー/時計")
handmade_3.children.create([{name: "アクセサリー(男性用)"},{name: "時計(女性用)"},{name: "時計(男性用)"},{name: "その他"}])
handmade_4 = handmade.children.create(name: "日用品/インテリア")
handmade_4.children.create([{name: "キッチン用品"},{name: "家具"},{name: "文房具"},{name: "アート/写真"},{name: "アロマ/キャンドル"},{name: "フラワー/ガーデン"},{name: "その他"}])
handmade_5 = handmade.children.create(name: "趣味/おもちゃ")
handmade_5.children.create([{name: "クラフト/布製品"},{name: "おもちゃ/人形"},{name: "その他"}])
handmade_6 = handmade.children.create(name: "キッズ/ベビー")
handmade_6.children.create([{name: "ファッション雑貨"},{name: "スタイ/よだれかけ"},{name: "外出用品"},{name: "ネームタグ"},{name: "その他"}])
handmade_7 = handmade.children.create(name: "素材/材料")
handmade_7.children.create([{name: "各種パーツ"},{name: "生地/糸"},{name: "型紙/パターン"},{name: "その他"}])
handmade_8 = handmade.children.create(name: "二次創作物")
handmade_8.children.create([{name: "Ingress"},{name: "クリエイターズ宇宙兄弟"},{name: "その他"},{name: "チケット"},{name: "すべて"}])
handmade_9 = handmade.children.create(name: "その他")
handmade_9.children.create([{name: "すべて"}])

# チケット
ticket = Category.create(name: "チケット")
ticket_1 = ticket.children.create(name: "音楽")
ticket_1.children.create([{name: "男性アイドル"},{name: "女性アイドル"},{name: "韓流"},{name: "国内アーティスト"},{name: "海外アーティスト"},{name: "音楽フェス"},{name: "声優/アニメ"},{name: "その他"}])
ticket_2 = ticket.children.create(name: "スポーツ")
ticket_2.children.create([{name: "サッカー"},{name: "野球"},{name: "テニス"},{name: "格闘技/プロレス"},{name: "相撲/武道"},{name: "ゴルフ"},{name: "バレーボール"},{name: "バスケットボール"},{name: "モータースポーツ"},{name: "ウィンタースポーツ"},{name: "その他"}])
ticket_3 = ticket.children.create(name: "演劇/芸能")
ticket_3.children.create([{name: "ミュージカル"},{name: "演劇"},{name: "伝統芸能"},{name: "落語"},{name: "お笑い"},{name: "オペラ"},{name: "サーカス"},{name: "バレエ"},{name: "その他"}])
ticket_4 = ticket.children.create(name: "イベント")
ticket_4.children.create([{name: "声優/アニメ"},{name: "キッズ/ファミリー"},{name: "トークショー/講演会"},{name: "その他"}])
ticket_5 = ticket.children.create(name: "映画")
ticket_5.children.create([{name: "邦画"},{name: "洋画"},{name: "その他"}])
ticket_6 = ticket.children.create(name: "施設利用券")
ticket_6.children.create([{name: "遊園地/テーマパーク"},{name: "美術館/博物館"},{name: "スキー場"},{name: "ゴルフ場"},{name: "フィットネスクラブ"},{name: "プール"},{name: "ボウリング場"},{name: "水族館"},{name: "動物園"},{name: "その他"}])
ticket_7 = ticket.children.create(name: "優待券/割引券")
ticket_7.children.create([{name: "ショッピング"},{name: "レストラン/食事券"},{name: "フード/ドリンク券"},{name: "宿泊券"},{name: "その他"}])
ticket_8 = ticket.children.create(name: "その他")
ticket_8.children.create([{name: "すべて"}])


# 自動車・オートバイ
car_motorcycle = Category.create(name: "自動車・オートバイ")
car_motorcycle_1 = car_motorcycle.children.create(name: "自動車本体")
car_motorcycle_1.children.create([{name: "国内自動車本体"},{name: "外国自動車本体"}])
car_motorcycle_2 = car_motorcycle.children.create(name: "自動車タイヤ/ホイール")
car_motorcycle_2.children.create([{name: "タイヤ/ホイールセット"},{name: "タイヤ"},{name: "ホイール"},{name: "その他"}])
car_motorcycle_3 = car_motorcycle.children.create(name: "自動車パーツ")
car_motorcycle_3.children.create([{name: "サスペンション"},{name: "ブレーキ"},{name: "外装、エアロパーツ"},{name: "ライト"},{name: "内装品、シート"},{name: "ステアリング"},{name: "マフラー・排気系"},{name: "エンジン、過給器、冷却装置"},{name: "クラッチ、ミッション、駆動系"},{name: "電装品"},{name: "補強パーツ"},{name: "汎用パーツ"},{name: "外国自動車用パーツ"},{name: "その他"}])
car_motorcycle_4 = car_motorcycle.children.create(name: "自動車アクセサリー")
car_motorcycle_4.children.create([{name: "車内アクセサリー"},{name: "カーナビ"},{name: "カーオーディオ"},{name: "車外アクセサリー"},{name: "メンテナンス用品"},{name: "チャイルドシート"},{name: "ドライブレコーダー"},{name: "レーダー探知機"},{name: "カタログ/マニュアル"},{name: "セキュリティ"},{name: "ETC"},{name: "その他"}])
car_motorcycle_5 = car_motorcycle.children.create(name: "オートバイ車体")
car_motorcycle_5.children.create([{name: "すべて"}])
car_motorcycle_6 = car_motorcycle.children.create(name: "オートバイパーツ")
car_motorcycle_6.children.create([{name: "タイヤ"},{name: "マフラー"},{name: "エンジン、冷却装置"},{name: "カウル、フェンダー、外装"},{name: "サスペンション"},{name: "ホイール"},{name: "シート"},{name: "ブレーキ"},{name: "タンク"},{name: "ライト、ウィンカー"},{name: "チェーン、スプロケット、駆動系"},{name: "メーター"},{name: "電装系"},{name: "ミラー"},{name: "外国オートバイ用パーツ"},{name: "その他"}])
car_motorcycle_7 = car_motorcycle.children.create(name: "オートバイアクセサリー")
car_motorcycle_7.children.create([{name: "ヘルメット/シールド"},{name: "バイクウエア/装備"},{name: "アクセサリー"},{name: "メンテナンス"},{name: "カタログ/マニュアル"},{name: "その他"}])

# その他
others = Category.create(name: "その他")
others_1 = others.children.create(name: "まとめ売り")
others_1.children.create([{name: "すべて"}])
others_2 = others.children.create(name: "ペット用品")
others_2.children.create([{name: "ペットフード"},{name: "犬用品"},{name: "猫用品"},{name: "魚用品/水草"},{name: "小動物用品"},{name: "爬虫類/両生類用品"},{name: "かご/おり"},{name: "鳥用品"},{name: "虫類用品"},{name: "その他"}])
others_3 = others.children.create(name: "食品")
others_3.children.create([{name: "菓子"},{name: "米"},{name: "野菜"},{name: "果物"},{name: "調味料"},{name: "魚介類(加工食品)"},{name: "肉類(加工食品)"},{name: "その他 加工食品"},{name: "その他"}])
others_4 = others.children.create(name: "飲料/酒")
others_4.children.create([{name: "コーヒー"},{name: "ソフトドリンク"},{name: "ミネラルウォーター"},{name: "茶"},{name: "ウイスキー"},{name: "ワイン"},{name: "ブランデー"},{name: "焼酎"},{name: "日本酒"},{name: "ビール、発泡酒"},{name: "その他"}])
others_5 = others.children.create(name: "日用品/生活雑貨/旅行")
others_5.children.create([{name: "タオル/バス用品"},{name: "日用品/生活雑貨"},{name: "洗剤/柔軟剤"},{name: "旅行用品"},{name: "防災関連グッズ"},{name: "その他"}])
others_6 = others.children.create(name: "アンティーク/コレクション")
others_6.children.create([{name: "雑貨"},{name: "工芸品"},{name: "家具"},{name: "印刷物"},{name: "その他"}])
others_7 = others.children.create(name: "文房具/事務用品")
others_7.children.create([{name: "筆記具"},{name: "ノート/メモ帳"},{name: "テープ/マスキングテープ"},{name: "カレンダー/スケジュール"},{name: "アルバム/スクラップ"},{name: "ファイル/バインダー"},{name: "はさみ/カッター"},{name: "カードホルダー/名刺管理"},{name: "のり/ホッチキス"},{name: "その他"}])
others_8 = others.children.create(name: "事務/店舗用品")
others_8.children.create([{name: "オフィス用品一般"},{name: "オフィス家具"},{name: "店舗用品"},{name: "OA機器"},{name: "ラッピング/包装"},{name: "その他"}])
others_9 = others.children.create(name: "その他")
others_9.children.create([{name: "すべて"}])

このままでは、テーブルに反映されないため、

tarminal
$ rails db:seed

ファイルを修正する場合は、

tarminal
$ rails db:migrate:reset

としてからファイル修正をしましょう。
修正後、再度$ rails db:seedとしてテーブルにデータを反映させます。

ここまでで、データ作成が完了です。

3. コード実装

items_controller.rb

items_controller.rb
class ItemsController < ApplicationController
  before_action :set_item, only:[:show, :destroy, :edit, :update, :purchase, :payment]

  def new
    @item = Item.new
    @item.item_images.new

    #セレクトボックスの初期値設定
    @category_parent_array = ["---"]
    #データベースから、親カテゴリーのみ抽出し、配列化
    @category_parent_array = Category.where(ancestry: nil)
  end

  # 以下全て、formatはjsonのみ
  # 親カテゴリーが選択された後に動くアクション
  def get_category_children
    #選択された親カテゴリーに紐付く子カテゴリーの配列を取得
    # ここでfind_byを使うことでレディーしか取れてなかった
    @category_children = Category.find(params[:parent_id]).children
  end
  
  # 子カテゴリーが選択された後に動くアクション
  def get_category_grandchildren
    #選択された子カテゴリーに紐付く孫カテゴリーの配列を取得
    @category_grandchildren = Category.find(params[:child_id]).children
  end
end
  • 初めは、親要素のみを表示させるため、newメソッドには親要素についてのみ記述します。
    • @category_parent_array = Category.where(ancestry: nil)
    • これは、categoryテーブルを確認すると、ancestryカラムがnilになっているものが親要素を示します。
  • 子要素と孫要素はjsonで使用するので、それぞれメソッドを作成しています。

new.html.haml

次に親要素のビューを作成します。
カテゴリに該当する部分だけを記載しています。

new.html.haml
.exhibitionPage
  .exhibitionPage__main
    .exhibitionPage__main__contents
      = form_with(model: @item, local: true) do |form|
        .exhibitionPage__main__contents__detail
          .exhibitionPage__main__contents__detail__title
            %h1 商品の詳細
          .exhibitionPage__main__contents__detail__category
            .exhibitionPage__main__contents__detail__category__title
              %label.sab-title カテゴリー
              %span.required 必須
            .exhibitionPage__main__contents__detail__category__choose
              = form.collection_select :category_id, Category.where(ancestry: nil), :id, :name, {prompt: '---'}, {id: 'parent_category'}
  • コントローラーでわざわざ@category_parent_array = Category.where(ancestry: nil)としているのに、ビューではCategory.where(ancestry: nil)としているのはなぜか起こるエラーを避けるためです。

初学者の私はこのform部分を書くだけでも、書き方がよく分からず、メンターさんのお世話になりました。

routes.rb

ルーティングにて、Ajaxで動くアクションのルートを作成します。

routes.rb
resources :items do 
  #Ajaxで動くアクションのルートを作成
  collection do
    get 'category/get_category_children', to: 'items#get_category_children', defaults: { format: 'json' }
    get 'category/get_category_grandchildren', to: 'items#get_category_grandchildren', defaults: { format: 'json' }
  end
end

jbuilderファイル

get_category_children.json.jbuilder
json.array! @category_children do |child|
  json.id child.id
  json.name child.name
end
get_category_grandchildren.json.jbuilder
json.array! @category_grandchildren do |grandchild|
  json.id grandchild.id
  json.name grandchild.name
end

category.js

最後に、category.jsの記述です。

category.js
$(document).on('turbolinks:load', function(){
  $(function(){
    // カテゴリーセレクトボックスのオプションを作成
    function appendOption(category){
      var html = `<option value="${category.id}" data-category="${category.id}">${category.name}</option>`;
      return html;
    }
    // 子カテゴリーの表示作成
    function appendChidrenBox(insertHTML){
      var childSelectHtml = '';
      childSelectHtml = `<div class='exhibitionPage__main__contents__detail__category__choose__added' id= 'children_wrapper'>
                          <div class='exhibitionPage__main__contents__detail__category__choose1'>
                            <i class='fas fa-chevron-down exhibitionPage__main__contents__detail__category__choose--arrow-down'></i>
                            <select class="exhibitionPage__main__contents__detail__category__choose--select" id="child_category" name="item[category_id]">
                              <option value="---" data-category="---">---</option>
                              ${insertHTML}
                            <select>
                          </div>
                        </div>`;
      $('.exhibitionPage__main__contents__detail__category__choose').append(childSelectHtml);
    }

    // 孫カテゴリーの表示作成
    function appendGrandchidrenBox(insertHTML){
      var grandchildSelectHtml = '';
      grandchildSelectHtml = `<div class='exhibitionPage__main__contents__detail__category__choose__added' id= 'grandchildren_wrapper'>
                                <div class='exhibitionPage__main__contents__detail__category__choose2'>
                                  <i class='fas fa-chevron-down exhibitionPage__main__contents__detail__category__choose--arrow-down'></i>
                                  <select class="exhibitionPage__main__contents__detail__category__choose__box--select" id="grandchild_category" name="item[category_id]">
                                    <option value="---" data-category="---">---</option>
                                    ${insertHTML}
                                  </select>
                                </div>
                              </div>`;
      $('.exhibitionPage__main__contents__detail__category__choose').append(grandchildSelectHtml);
    }

    // 親カテゴリー選択後のイベント
    $('#parent_category').on('change', function(){
      var parent_category_id = document.getElementById
      ('parent_category').value; //選択された親カテゴリーの名前を取得
      if (parent_category_id != "---"){ //親カテゴリーが初期値でないことを確認
        $.ajax({
          url: '/items/category/get_category_children',
          type: 'GET',
          data: { parent_id: parent_category_id },
          dataType: 'json'
        })
        .done(function(children){
          $('#children_wrapper').remove(); //親が変更された時、子以下を削除する
          $('#grandchildren_wrapper').remove();
          var insertHTML = '';
          children.forEach(function(child){
            insertHTML += appendOption(child);
          });
          appendChidrenBox(insertHTML);
        })
        .fail(function(){
          alert('カテゴリー取得に失敗しました');
        })
      }else{
        $('#children_wrapper').remove(); //親カテゴリーが初期値になった時、子以下を削除する
        $('#grandchildren_wrapper').remove();
      }
    });

    // 子カテゴリー選択後のイベント
    $('.exhibitionPage__main__contents__detail__category').on('change', '#child_category', function(){
      var child_category_id = $('#child_category option:selected').data('category'); //選択された子カテゴリーのidを取得
      if (child_category_id != "---"){ //子カテゴリーが初期値でないことを確認
        $.ajax({
          url: '/items/category/get_category_grandchildren',
          type: 'GET',
          data: { child_id: child_category_id },
          dataType: 'json'
        })
        .done(function(grandchildren){
          if (grandchildren.length != 0) {
            $('#grandchildren_wrapper').remove(); //子が変更された時、孫以下を削除する
            var insertHTML = '';
            grandchildren.forEach(function(grandchild){
              insertHTML += appendOption(grandchild);
            });
            appendGrandchidrenBox(insertHTML);
          }
        })
        .fail(function(){
          alert('カテゴリー取得に失敗しました');
        })
      }else{
        $('#grandchildren_wrapper').remove(); //子カテゴリーが初期値になった時、孫以下を削除する
      }
    });
  });
});

ポイントを見ていきましょう

  1. $.ajax({ url: '/items/category/get_category_children'$.ajax({ url: '/items/category/get_category_grandchildren'
  • これらを絶対パスで書いている点。
  • validation errorを起こさず1発で商品情報を登録させるなら、相対パスであるurl: '/category/get_category_children'url: '/category/get_category_grandchildren'と書いても問題はありません。
  • しかし、errorを発生させてrender :newさせた時、ページのパスが変わるため、相対パスだとjsが動作しなくなります。そのためここは絶対パスで書きましょう。
  1. <div class='exhibitionPage__main__contents__detail__category__choose1'><div class='exhibitionPage__main__contents__detail__category__choose2'>のクラス名
  • これらに数字をつけている点。
  • 元のnew.html.hamlファイルのクラス名.exhibitionPage__main__contents__detail__category__chooseと別名にするため。
  • 同じクラス名にすると、子要素を選択した時点で、孫要素のボックスが2つになってしまうため、最後に数字をつけて変えています。
  1. $(document).on('turbolinks:load', function(){
  • turbolinks:loadがあることで、商品出品ページに飛んだ時、リロードせずにカテゴリのjsが動作するようになります。

# まとめ
以上、長々と書きましたが、お読みいただきありがとうございます。
jsが苦手なこともあり、このパートの実装は非常に苦労しました。
類似した記事もありますが、そのまま用いてもうまく動作しなかったため、私の場合はこのように記述した、という記録のために作成いたしました。
後学者の助けになれば幸いです。

# 参考にさせていただいた記事

7
14
0

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
7
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?