主キーと連結モデルを変更し関係データを取得

Cakephpのモデルはフレキシブル

Cakephpでは、仮にデータベース側のデータ構造に十分でない点があってもCakephpのモデルで柔軟にカバーできる機能が複数備わっている。モデルの主キーを操作する関数だったり、モデルのアソシエート先を変更する機能を活用して関係するデータの構成することができる。

以下はCakephpでページネーションを構成する処理。Productモデルには、Counterモデルとhasoneのアソシエーションが設定されている。つまり、

Product(商品)は、Counter(カウント)を持つ

という関係がCakephpのモデルレベルで定義されている。なお、ProductとCounterがidという共通のフィールドで連結されるものと想定している。

$this->paginate = array(
	'page'=>1,
	'conditions'=>array('Product.status' => '1'),
	'sort'=>'datetime',
	'limit'=>20,
	'order' => array('start_datetime' => 'desc'),
	'direction'=>'desc',
	'recursive'=>0
);
$data = $this->paginate();

上のコードによりモデルから20件のデータを取得できる。ProductとCounterはidフィールドで1対1で対応しているので、それぞれの商品とカウンタが対応したデータ構造が$dataに格納される。ここまではCakephpの通常のページネート処理である。

primaryKeyとbindModelでデータベースを異なるレイヤーで変更してしまう

システムやサービスの拡張によりShopモデルが新設され、Productモデルと連結させる必要が生じた場合を考えてみたい。連結させたいがCounterの場合と異なり、idという共通のフィールドをProductとShopが共有していない場合を想定している。

その場合には、主キーを変更し、アソシエート先モデルを動的に変更することで対応できる。具体的には、

$this->Product->primaryKey = 'email';

上の処理で主キーがemailにcakephpのモデルレベルで変更される。ProductモデルとShopモデルはemailというフィールドを共有していることを想定している。そして、アソシエートを構成し直す、

$this->Product->unbindModel(array('hasOne' => array('Counter')), false);
$this->Product->bindModel(array('hasOne' => array('Shop' => array('className' => 'Shop', 'foreignKey' => 'email'))), false);

Counterのアソシエーションを解除した後、Shopモデルに対して連結処理を行っている。そのためのモデル関数がbindModelで、cakephpの動的アソシエーションに有効に活用できる機能だったりする。ここまで準備をしたらさきほどと同じpaginate処理を実行する。

$this->paginate = array(
	'page'=>1,
	'conditions'=>array('Product.status' => '1'),
	'sort'=>'datetime',
	'limit'=>20,
	'order' => array('start_datetime' => 'desc'),
	'direction'=>'desc',
	'recursive'=>0
);
$data_store = $this->paginate();

paginate処理は同一でも返されるデータ構造はさきほどとは異なり、productモデルとshopモデルで構成されたデータ構造が返される。意図的に返されたデータを先ほどとは異なる変数に格納している。最後にphpレベルでデータの構造を操作し、関係データとして構成している。

$data_store_c = count($data_store);
for( $i = 0; $data_store_c > $i; $i++ )
{
	$data[$i]['Shop'] = $data_store[$i]['Shop'];
}

$dataには、productとcounter、そしてshopというモデルで構成された、それぞれが関係するデータ構造を取得できる。

Cakephpには、システムやサービスの拡張や変更に伴い、柔軟に構成を変え対応していける機能が豊富に備わっている。

Webエンジニアブログにコメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

主キーと連結モデルを変更し関係データを取得の記事にコメントを投稿