CodeIgniterにリレーション解決サポートを
CodeIgniterにリレーション解決をサポートするライブラリを書きました。librariesに入れてload->library()で使います。
CodeIgniterにはSQLクェリビルダはあるけど、エンティティの関連性を補助する機能がまるでありません。あるレコードに関連する別のレコードを拾いつつ、オブジェクトのツリーを構築するとき、そこそこ面倒なコードを書かないといけません。
<?php // $rowは事前にフェッチしていた行 $this->db->where('id', $row->parent_id); $r = $this->db->get('parents_table'); $row->parent = $r->row(); ?>
O/Rマッピングエンジンほど賢くないけど、この(*:1)関連づけコードがこうなります。
<?php $this->relations->ref($row, 'parent', // 注入するフィールド 'parents_table', // 関連テーブル 'parent_id' // 関連させる外部キー ); ?>
ビューティフル。だいぶ記号が減りました。
あと、has_many(1:*)とhas_many_ref(*:*)もあります。O/Rマッパーにありがちな多重度って、こんなもんかな?(1:1)はたぶん、refでいけると思います。
DAOの実装を簡単にするために、遅延フェッチのあるほんとのActiveRecordパターンなドメインクラスを書こうとも思ったけど、CIはコントローラ内でトランザクションを切ってしまわないといけないので、遅延フェッチは没でした。いろいろ試行錯誤の末、やることを変えずに書き方を変えれば、コードの読み書きがだいぶマシになる、っていうのにとどめることにし、類似箇所がいっぱいあるので、せめてライブラリにしようとなりました。でも、意外とこれがイケてた。ライブラリのインターフェースを考え直し、たぶん、最小コード量になるインターフェースとして、こんなのがいいんじゃないかと思っています。
Model assosiation support for CodeIgniter
まあ、CI使うかぎりは(画面に出ないものは取ってこないような)手でチューニングして、「表」を主体に書くのが普通なんだろうな。ネストする構造はジョインして表形式にしてしまう、とか。
現時点では、ライセンスもバージョンもない実験コードなので、そこんとこヨロシクで(w データベースもデフォルトの1個しか想定してないし。