2007/8/25 土曜日

Zend Frameworkで多対多のテーブルを簡単に扱う。

Filed under: Zend Framework — ne-zu @ 3:43:35 このエントリをはてなブックマークに追加

いろいろとややこしい多対多のテーブル関連の操作をZend Frameworkで簡単に行えます。
前提として、RDBMS上ですでにリレーションの設定を行っているものを扱います。そちらのほうが簡単なので。

多対多リレーションとか関係テーブルとか、マッピングテーブルとかいわれてるテーブルの設定。

PHP:
  1. class BugsProducts extends Zend_Db_Table_Abstract
  2. {
  3.     protected $_name = 'BugsProducts';
  4.  
  5.     protected $_referenceMap    = array(
  6.         'Bug' => array(
  7.             'columns'           => 'bug_id',
  8.             'refTableClass'     => 'Bugs',
  9.             'refColumns'        => 'id'
  10.         ),
  11.         'Product' => array(
  12.             'columns'           => 'product_id',
  13.             'refTableClass'     => 'Products',
  14.             'refColumns'        => 'id'
  15.         )
  16.     );
  17.  
  18. }

(設定はZFマニュアルに載っているのを参考に、少し変更しました。あまり深く考える必要は無いのですが、まあ、BugsとProductsの多対多、1つの製品に多数のバグがあり、1つのバグが製品群に横行していることもある、といったテーブルでしょうか)
上記の様に親テーブルにリファレンスを張って、

PHP:
  1. $products = new Products();
  2. $bug_list = $products->find(10)->current()
  3. ->findManyToManyRowset('Bugs', 'BugsReports');

で、$bug_listには、多対多テーブルで product_id=10 と関連付けられている (bugsテーブルの)bugのRowsetが入っているという。。
今時のフレームワーク、O/Rマッパーなどでは当たり前の機能なのかもしれませんが、こんなに簡単に操作できて感動しました。

RDBMS上でリレーションを組んでおけば、Zend_Db_Tableの設定で 親側のテーブルに $_dependentTables を指定しなくてもよいので楽です。

マニュアルには、

注意

RDBMS サーバが実装している参照整合性制約によって連鎖操作を行う場合は、 $_dependentTables を宣言しません。 詳細は 項9.8.6. 「書き込み操作の連鎖」 を参照ください。

と書いてあります。$_referenceMapも自動で張ってくれると楽なんですけどねえ。

findManyToManyの書き方は色々とあるようですので、マニュアルを参照してください。

PHP:
  1. $row->find<TableClass>Via<IntersectionTableClass>()
  2. $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>()
  3. $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>()

関連する記事:

Powered by

コメント (1) »

  1. Zend_Table_Rowから呼び出すとはいえ、このリレーションだと $products->find(10)->current() で product_id=10を出すところって無駄でしかないよね。id分かってるんだし。

    コメント by ne-zu — 2007/8/25 土曜日 @ 4:03:03

コメント RSS トラックバック URL

コメントをどうぞ

Powered by PHP-SeeD and WordPress ME