ancestryを利用してRailsのモデルにディレクトリ構造を定義する

はじめに

データの保持にディレクトリ構造を求められるケースって、割と多くあると思います。ここはwindowsのフォルダみたいな感じにしてよ、とかお客さんから軽い調子で求められて、実はそれって意外と面倒臭いんですよ、などとお答えすると、しょっぱい顔をされるアレでございます。

そんなときに便利なのが、Ancestryというgemです。こちらを利用すると、非常に簡単にディレクトリ構造を定義することができます。え、それって本当に使っても大丈夫なの? という疑問も浮かびますが、ここ数年ほどウォッチしていた限り、Railsへの追従も頻繁に行われており、当面は問題ないように思われます。

実装

なにはともあれ、gemをインストールします。

gem install ancestry

Ancestryは親子関係を表現する為の木構造を対象モデルのテーブルに保存します。なので、マイグレーションファイルを追加する必要があります。今回はfolderというモデルに対して、ディレクトリ構造を与えることとします。

最後に対象となるモデルへ、Ancestryを利用する旨、一筆入れます。

上記のコードにより、幾つかのメソッドがモデルに生えます。こちらを利用することで、特定のインスタンスに対して、その親インスタンスや子インスタンス、はたまた関連しているインスタンスのサブツリーなどを取得することができます。

一体どのようにして木構造が実装されているのかというと、裏ではMySQLのLIKE検索が動いております。なので幾つかのメソッドについては、そのままActiveRecord::Relationのチェーンを繋げて、scopeを定義することも可能です。

irb(main):003:0> Folder.first.subtree.to_sql
Folder Load (1.3ms) SELECT `folders`.* FROM `folders` ORDER BY `folders`.`id` ASC LIMIT 1
=> "SELECT `folders`.* FROM `folders` WHERE ((`folders`.`ancestry` LIKE '1/%' OR `folders`.`ancestry` = '1') OR `folders`.`id` = 1)"

とても便利ですね。気に入っているgemの一つでございます。

Rails

Posted by poison