開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina
前提
下記実装済み。
実装
1.Gemを導入
Gemfile
# 追記
gem 'ancestry'
ターミナル
$ bundle
2.カラムを追加
データ量がかなり多くなるのでindex
を張ります。
ターミナル
$ rails g migration AddAncestryToCategory ancestry:string:index
ターミナル
$ rails db:migrate
schema.rb
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "ancestry"
t.index ["ancestry"], name: "index_categories_on_ancestry"
end
3.モデルを編集
category.rb
# 追記
has_ancestry
has_ancestry
➡︎ ancestryを使える様になる。
メソッド一覧
メソッド名 | 返り値 |
---|---|
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 | ノードの深さを返す |
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つですが、親ではない |
階層構造
親:ビジネス
子:経済
孫:日本経済、国際経済
本のカテゴリーに上記の様な親子関係を持たせたい場合は、以下の様にデータを作成します。
business = Category.create(name: 'ビジネス')
business_economy = business.children.create(name: '経済')
business_economy.children.create([{ name: '日本経済' }, { name: '国際経済' }])
カラム構造
id | name | ancestry |
---|---|---|
1 | ビジネス | nil |
2 | 経済 | 1(親のid) |
3 | 日本経済 | 1/2(親のid/子のid) |
4 | 国際経済 | 1/2(親のid/子のid) |