多階層カテゴリでancestryを使ったら便利すぎた

多階層カテゴリを扱おうとして、いろいろ苦労したことと、
結局はancestryというgemを使ってうまくいった（多分）という話です。

#完成イメージ
(一部ですが、、、）
・親カテゴリ/子カテゴリ/孫カテゴリがあって、カテゴリ同士に３層の関係性ができている。
・それぞれのカテゴリにアイテムが入っており、カテゴリ分けによってアイテム検索できる。
<img width="1026" alt="スクリーンショット 2019-04-20 0.01.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/6a91a2da-5e4d-acf9-6997-595b7609ce1a.png">

#①DB設計

当初、アイテムとカテゴリは多対多になるから中間テーブル作って、カテゴリは細分化して入れとけばいいやろ。
と思ってました、、、
↓当初のER図
<img width="749" alt="スクリーンショット 2019-04-19 23.49.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/a66db683-2de7-7d33-2678-8230598062b1.png">

いざ進めてみると、親子孫の関係性なくね？となり変更。
多階層カテゴリの管理は様々な方法があるようですが、呼び出しがシンプルな
Path Enumeration（経路列挙型）でDBを作成することにしました。

経路をカラムで管理して、経路(Path)基準で表示させましょう、という感じです（あいまいですが）
↓こんな感じ

| id | path | item |
|--:|:--|:--|
| 1 | null | レディース |
| 2 | 1| トップス |
| 3 | 1/2| Tシャツ |

https://kyabatalian.hatenablog.com/entry/2016/12/19/193430
（参考にさせていただいた記事です）

#②導入
https://github.com/stefankroes/ancestry
↑に従えばOKです！

## Gemfile

```rb
gem 'ancestry'
```
```rb
$ bundle install
$ rails g migration add_ancestry_to_[table] ancestry:string:index
$ rake db:migrate
```
```rb
class Category < ApplicationRecord
　　　   has_many :item_categories
	has_many :items, through: :item_categories
	has_ancestry
end
#カテゴリーモデルにアンセストリーを使うよ、って書いておく
```
~~準備完了！~~
↓（ancestoryを使えば多対多でなく、一対多で良さそうです）


```rb
class Item < ApplicationRecord

　belongs_to user, foreign_key: 'user_id'
　belongs_to :category
  #(中略
end
```
```rb
class Category < ApplicationRecord
　has_many :items
　has_ancestry
end
```
<img width="942" alt="スクリーンショット 2019-05-26 13.19.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/4fdf3b24-c5e3-3788-3956-a2268197b7fa.png">


#③レコード投入！

seeds.rb

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

lady_tops = lady.children.create(:name=>"トップス")
lady_jacket = lady.children.create(:name=>"ジャケット/アウター")

lady_tops.children.create([{:name=>"Tシャツ/カットソー(半袖/袖なし)"}, {:name=>"Tシャツ/カットソー(七分/長袖)"},{:name=>"その他"}])
lady_jacket.children.create([{:name=>"テーラードジャケット"}, {:name=>"ノーカラージャケット"}, {:name=>"Gジャン/デニムジャケット"},{:name=>"その他"}])

```
ancestryを入れるとchildrenと記述することで直前の変数の子要素として扱うことができます！
なのでレディース（親）トップス（子）Tシャツ（孫）という関係性をレコード作成の時にGemがやってくれるのです！

```
$ rake db:seed
```
```
1	レディース	NULL
2	メンズ	NULL
：
13	その他	NULL
14	トップス	1
15	ジャケット/アウター	1
：
19	その他	1
20	Tシャツ/カットソー(半袖/袖なし)	1/14
21	Tシャツ/カットソー(七分/長袖)	1/14
22	シャツ/ブラウス(半袖/袖なし)	1/14
23	シャツ/ブラウス(七分/長袖)	1/14
：
```
レコード投入完了！

#④Viewで表示

#####コントローラー

```rb
def index
  @parents = Category.all.order("id ASC").limit(13)
end
#１層目が１３個なのでlimit(13)
```

#####ビュー　親要素

```rb
- @parents.each do |parent|
 =parent.name
```
↓
<img width="728" alt="スクリーンショット 2019-04-20 0.52.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/44f1b441-d477-748a-041b-a7b4e6237cc7.png">
*CSSは別途当ててます



#####子要素

```rb
：
- parent.children.each do |child|
 =child.name									
```
<img width="1031" alt="スクリーンショット 2019-04-20 0.54.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/c931c222-3832-f64e-709d-0a7290f399e7.png">

#####孫要素

```rb
：
- child.children.each do |grandchild|
  =grandchild.name

#ちなみに、=grandchild.parent.nameとするとgrandchildrenの親要素を取得できます！
```

<img width="1031" alt="スクリーンショット 2019-04-20 0.54.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/4cbaa8bc-771f-ddf6-8ecb-ce4316000cd1.png">

#⑤結論
便利すぎます。

呼び出しがシンプルでいいですね。
子から親も呼べますので、いろいろな使い方ができるかも？

まだancestryに関するQiitaの記事は少ないように感じますので、
できればGithubのReadMeを参照にすべきかと考えております。

間違っている点、改善点などありましたらコメントいただけますと幸いです:relieved:

#参考にさせていただいた記事
https://kyabatalian.hatenablog.com/entry/2016/12/19/193430
https://techracho.bpsinc.jp/hira/2018_03_15/53872
https://qiita.com/NAKANO_Akihito/items/d42a6ceae40933af2352
https://github.com/stefankroes/ancestry