ancestryとは
AncestryはRuby on RailsのActiveRecordモデルのレコードをツリー構造(階層)として編成することを可能にするGemのことです。
親・子・孫等の、すべてのツリー構造の関係の編成を簡単に出来ます。
使い方
※親子孫のツリー構造を作成するとします。
1.Gemfaileに以下を記述する。
gem 'ancestry'
忘れず実行する
$ bundle install
2.モデルを作成する
$ rails g model category name:string
忘れず実行する。
$ rails db:migrate
3.先ほど作ったcategoriesテーブルにancestryのカラムを作成する
$ rails g migration add_ancestry_to_category ancestry:string:index
忘れず実行する。
$ rails db:migrate
4.モデルにancestryを明示する
category.rb
class Category < ApplicationRecord
~省略~
has_ancestry
end
5.ancestryのメソッドを用いてデータ挿入する
Ancestryモデルを操作するには、以下のインスタンスメソッドを使用できます。
| method | return value |
|---|---|
| parent | 親レコードを取得 |
| parent_id | 親レコードのIDを取得 |
| root | レコードのルートを取得 |
| root_id | レコードのルートIDを取得 |
| root? | |
| is_root? | レコードがルートであれば、trueを返す |
| ancestors | ルートで始まり、親で終わる、レコードの祖先を返す |
| ancestors? | レコードに祖先(ルートノードではない)がある場合はtrueを返す |
| ancestor_ids | レコードの祖先のIDを返す |
| path | ルートで始まり、自己で終わる、レコードのパスを返す |
| path_ids | ルートIDで始まり、 自己のIDで終わるパスのIDをリストで返す |
| children | 子レコードを取得 |
| child_ids | 子レコードのIDを取得 |
| has_parent? | |
| ancestors? | レコードが親を持っていれば、trueを返す |
| has_children? | |
| children? | レコードが子を持っていれば、trueを返す |
| is_childless? | |
| childless? | レコードが子を持っていなければ、trueを返す |
| siblings | 兄弟レコード(同じ階層のレコード)を返す |
| sibling_ids | 兄弟レコード(同じ階層のレコード)のIDを返す |
| has_siblings? | |
| siblings? | レコードの親に複数の子がある場合はtrueを返す |
| is_only_child? | |
| only_child? | レコードが親の唯一の子である場合はtrueを返す |
| descendants | 子レコード、孫レコード、曽孫レコード... を返す |
| descendant_ids | 子レコード、孫レコード、曽孫レコード... のIDを返す |
| indirects | 孫レコード以下を返す |
| indirect_ids | 孫レコード以下のIDを返す |
| subtree | 子孫と自己のモデルを返す |
| subtree_ids | レコードのサブツリーのIDをリストで返す |
| depth | ノードの深さを返す |
レコードがルートの場合、他のルートレコードは兄弟と見なされます。兄弟はレコード自体を返す。
2つのノード間の関係を判別するインスタンスメソッドもあります。
| method | return value |
|---|---|
| parent_of?(node) | このレコードを(node)の親にする |
| root_of?(node) | このレコードを(node)のルートにする |
| ancestor_of?(node) | (node)の祖先にはこのレコードが含まれる |
| child_of?(node) | (node)はレコードの親 |
| descendant_of?(node) | (node)はこのレコードの祖先の1つ |
| indirect_of?(node) | (node)はこのレコードの祖先の1つですが、親ではない |
上記の表を見本としてseeds.rbにデータを入れていく
seeds.rb
# 一階層目
lady = Category.create(name: "レディース")
# 二階層目
lady_1 = lady.children.create(name: "トップス")
# 三階層目
lady_1.children.create([{:name=>"すべて"}, {:name=>"Tシャツ/カットソー(半袖/袖なし)"},{:name=>"Tシャツ/カットソー(七分/長袖)"}])
データを入れ終わったら、、、
$ rails db:seed
この表のようなデータが作成される。
| id | name | ancestry |
|---|---|---|
| 1 | レディース | nil |
| 2 | トップス | 1 |
| 3 | すべて | 1/2 |
| 4 | Tシャツ/カットソー(半袖/袖なし) | 1/2 |
| 5 | Tシャツ/カットソー(七分/長袖) | 1/2 |