#はじめに
Gem Ancestryの公式ドキュメントを翻訳していきます。
公式ドキュメント:https://github.com/stefankroes/ancestry
#Ancestryとは
AncestryはRuby on RailsのActiveRecordモデルのレコードをツリー構造(階層)として編成することを可能にするGemです。
マテリアライズドパスパターン(※)を使用して、単一のデータベース列を使用します。
※パス文字列表現にてツリー構造を表現する方法
すべてのツリー構造の関係(祖先、親、ルート、子、兄弟、子孫)を公開し、すべて単一のSQLクエリで取得することができます。
その他の機能:
- STIサポート
- スコープ
- デプスキャッシング
- デプス制約
- 古いgemからの簡単な移行
- インテグリティチェック
- インテグリティ回復
- ハッシュへの(サブ)ツリーの配置
サポート情報:
- Ancestry 2.x supports Rails 4.1, and earlier
- Ancestry 3.x supports Rails 5.0, and 4.2
- Ancestry 4.0 only supports rails 5.0 and higher
#インストール方法
##インストール
- Gemファイルに追加
gem 'ancestry'
- bundle installを実行
$ bundle install
##Ancestryカラムをテーブルに追加する
- migrationファイルを作る
$ rails g migration add_ancestry_to_[table] ancestry:string:index
- データベースにマイグレートする
$ rake db:migrate
##モデルにAncestryを追加する
- app/models/.rb に記述する
class [Model] < ActiveRecord::Base
has_ancestry
end
- インストール完了
#has_ancestryの代わりにacts_as_treeを使用する
バージョン1.2.0では、単一のアプリケーションでacts_as_tree GemとAncestry gemの両方を使用できるようにするために
acts_as_treeメソッドはhas_ancestryに名前が変更されました。
メソッドacts_as_treeは、今後もサポートされる予定です。
#レコードをツリーにまとめる
レコードをツリーに整理するためにparent属性を使うことができます。
親として使用したいレコードのIDがあり、それをフェッチしたくない場合は、parent_idも使用できます。
他の仮想モデルの属性と同様に、parentとparent_idはレコードのparent =とparent_id =を使うか、
new、create、create!、update_attributesおよびupdate_attributes!に渡すハッシュに含めることで設定できます。
例えば:
TreeNode.create! :name => 'Stinky', :parent => TreeNode.create!(:name => 'Squeeky')
- ノードの関連付けを通して子モデルを作成することもできます。
node.children.create :name => 'Stinky'
#ツリーを操作する
- 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 | ノードの深さを返す |
※レコードがルートの場合、他のルートレコードは兄弟と見なされます。
Siblingsで兄弟ノードが取得できます。
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つですが、親ではない |
#ビジュアルガイド
大きなボーダーを持つノードは、すべて参照ノードで、ナビゲーションメソッドが呼び出されます。
黄色のノードは、メソッドによって返されるノードです。