CakePHP1.3.6:動的アソシエーションを使ってみる

先のログで使ったカテゴリーのメンテナンス画面を作ってみる。

モデルCategoryとItemはHABTMの関係にあるが、メンテナンスをする上では、カテゴリーを登録してから商品(Item)を登録する格好にする。なので、カテゴリーをメンテナンスする限りにおいては、Itemとのアソシエーションは必要ではない。

先のログでは、paginateのオプションのrecursiveを0、もしくは、-1にすることでアソシエーションを解除した。
だが、paginateを使わないアクションではどうしよう。

たとえば、showアクションみたいに、findByを使う場合など。方法は2つ(??)。

  • find('all')のオプションでrecursive=-1を指定する(findByでは、recursiveを指定できないようだ。こちらを参照)。
  • 動的にアソシエーションを解除する。

find('all')のオプションでrecursive=-1を指定する

			$this->data=$this->Category->find('all', array('conditions' => array('Category.id' => $param),
															'recursive' => -1));

この場合、取得される形式は以下。

Array ( 
	[0] => Array ( 
		[Category] => Array ( 
			[id] => 2 
			[name] => 飲み物 
			[memo] => 飲み物のメモ 
			[timestamp] => 2030-01-01 00:00:00 ) 
		) 
) 

動的にアソシエーションを解除する。

以下のコードを書いてみる。

<?php
class CategoriesController extends AppController{
	public $name = 'Categories';
	
	/**
	 * 
	 * データの照会
	 * $paramsにIdが入ってくる。
	 * 
	 */
	function show($param){
		$this->set('title_for_layout', "カテゴリーの詳細");
		$result=null;
		if(!empty($param)){
			
			// 動的なアソシエーションの解除
			$this->Category->unbindModel(array('hasAndBelongsToMany'=>array('Item')), false);
			// Idフィールドによる検索
			$this->data=$this->Category->findById($param);
			if(!$this->data){
				// 存在しないIDを参照された場合。
				$this->Session->setFlash('存在しません');
				$this->redirect('.');
			}
		}
		
		print_r($this->data);
	}	
}
?>


ここで、

		$this->Category->unbindModel(array('hasAndBelongsToMany'=>array('Item')), false);

で、CategoryとItemの間のアソシエーションを一時的に(fales)解除している。以下が出力される配列となる。findのときと形式が異なる。

Array ( 
	[Category] => Array ( 
		[id] => 2 
		[name] => 飲み物 
		[memo] => 飲み物のメモ 
		[timestamp] => 2030-01-01 00:00:00 
	) 
) 

逆に、動的にjoinしたい場合(というか、SQLのように自由にjoinしたい場合)には、bindModel(options)を使う。