シェアする

  • このエントリーをはてなブックマークに追加

[CakePHP2]Orderdビヘイビアでforeign_keyに複数のフィールドを反映させる

取り急ぎメモ。

OrderdビヘイビアをActsAsするときに、foreign_keyでソートを指定する範囲(特定のカテゴリー内でソートとか)を指定できるが、複数のフィールドを指定したい場合は、virtualFieldsを利用すればいい。

ex.店舗ID(shop_id) × メニューカテゴリーID(menu_category_id)でソート番号を振りたい場合

// HogeModel.php
class Hoge extends AppModel {
	public $virtualFields = array(
		'order_foreign_key' => 'CONCAT(Hoge.shop_id, "_",Hoge.menu_category_id)',
	);
	public $actsAs = array(
		'Orderd' => array(
			'field' => 'sort',
			'foreign_key' => 'order_foreign_key',
		),
	);
}

追記

virtualFieldsを利用した場合、Insertの時に該当のフィールドがないためエラーが出ることがわかりました。
そのため、次のように対応しました。(美しくないけど)

// HogeModel.php
class Hoge extends AppModel {
	public $virtualFields = array(
		'order_foreign_key' => 'CONCAT(Hoge.shop_id, "_",Hoge.menu_category_id)',
	);
	public $actsAs = array(
		'Orderd' => array(
			'field' => 'sort',
			'foreign_key' => 'order_foreign_key',
		),
	);
	// Insertの対応
	public function beforeValidate($options = array()) {
		// Orderdビヘイビアのforeign_key対策
		if (!empty($this->data[$this->alias]['shop_id']) && !empty($this->data[$this->alias]['menu_category_id'])) {
			// 無理やりforeign_keyを追加してやる
			$this->data[$this->alias]['orderd_foreign_key'] = $this->data[$this->alias]['shop_id'].'_'.$this->data[$this->alias]['menu_category_id'];
		}
	}
}

beforeSaveではなくbeforeValidateにしているのは、モデルのbeforeSaveの前にビヘイビアのbeforeSaveが走ってしまうためforeign_keyの設定が間に合わないからです。

検証もそこそこだけど多分これでいけるはず。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする