わかりました、他のアイデアがない限り、私は最善の解決策だと思うものを持っています.
OrderPrice の包含可能なオプションを変数としてモデルに保存するので、現在/元の価格を注文に結合したいときにいつでもそれらを書き直す必要はありません。どの機種からでも使えます。
次に、カスタム/元の価格を自動的に結合しながら、必要なパラメーターを使用して注文に対して通常のクエリを実行できるようにするカスタム検索タイプをいくつか用意します。
アプリ/モデル/OrderPrice.php
/**
* Containable array options for finding current price
*
* @var array
*/
public $containCurrent = array(
'fields' => 'OrderPrice.price',
'order' => 'OrderPrice.timestamp DESC',
'limit' => 1
);
/**
* Containable array options for finding the original price
*
* @var array
*/
public $containOriginal = array(
'fields' => 'OrderPrice.price',
'order' => 'OrderPrice.timestamp',
'limit' => 1
);
アプリ/モデル/注文.php
/**
* Custom find type which automatically joins the current order price
*
* @param string $state
* @param array $query
* @param array $results
* @return array
* @link http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#creating-custom-find-types
*/
protected function _findJoinCurrentPrice($state, $query, $results = array()) {
if ($state == 'before') {
$query['contain']['OrderPrice'] = $this->OrderPrice->containCurrent;
return $query;
} else {
$results = $this->_refinePriceFindResults($query, $results);
}
return $results;
}
/**
* Custom find type which automatically joins the original order price
*
* @param string $state
* @param array $query
* @param array $results
* @return array
* @link http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#creating-custom-find-types
*/
protected function _findJoinOriginalPrice($state, $query, $results = array()) {
if ($state == 'before') {
$query['contain']['OrderPrice'] = $this->OrderPrice->containOriginal;
return $query;
} else {
$results = $this->_refinePriceFindResults($query, $results);
}
return $results;
}
/**
* Refine the results of a custom price find
*
* If the find returns only one order and/or one price, the data for both
* models will be returned as element [0] of an otherwise empty array.
* This method modifies the results array by removing the redundant wrapper
* array, so that the model data is structured like a normal find('first').
*
* @param array $query The query array from the custom find method
* @param array $results The results array from the custom find method
* @return array The modified results
*/
protected function _refinePriceFindResults($query, $results) {
if (empty($results)) {
return false;
}
if (isset($query['conditions']['id']) || isset($query['conditions']['Order.id'])) {
$results = array_shift($results);
}
if (isset($results['OrderPrice']['0'])) {
if (count($results['OrderPrice']) == 1) {
$results['OrderPrice'] = array_shift($results['OrderPrice']);
}
}
return $results;
}
コントローラ
// I can perform a normal find, using any number of complex parameters.
$this->Order->find('joinCurrentPrice', array(
'fields' => array('Order.type_id'),
'conditions' => array('Order.id' => $id),
'contain' => array(
'Customer' => array(
'fields' => array('Customer.first_name', 'Customer.last_name')
)
)
));
// And the result is the same as the normal find, but the price model is
// automatically joined without any extra work.
array(
'Order' => array(
'type_id' => 2,
'id' => '843654'
),
'Customer' => array(
'id' => 7348,
'first_name' => 'Joe',
'last_name' => 'Bloggs'
),
'OrderPrice' => array(
'price' => '549.00',
'order_id' => '843654'
)
)
履歴価格に対してこれと同じことを行う方法を理解する必要があるだけで、注文履歴の最初または最後だけでなく、いつでも価格に参加できるようになります。