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個しか想定してないし。