LoginSignup
4
9

More than 3 years have passed since last update.

ancestryについて

Posted at

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
4
9
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
4
9