Динамическое виртуальное поле cakephp или обратный вызов beforeFind
В настоящее время я присоединяю виртуальное поле в beforeFind()
потому что мне нужно вставить идентификатор текущего пользователя в запрос. Вызов find для связанной модели и содержащий эту модель включает статически определенные виртуальные поля, но не одно в beforeFind()
.. Вызов find непосредственно на модели включает динамически присоединенное виртуальное поле.
Вот мой обратный вызов beforeFind:
public function beforeFind($query = array()) {
$user_id = $this->getCurrentUser()['id'];
$this->virtualFields = array_merge($this->virtualFields, array(
'cost_for_user' => sprintf('CASE WHEN Inventory.user_id = %s THEN Inventory.cost ELSE Inventory.cost_for_team END', $user_id),
));
return $query;
}
поскольку cost_for_user
динамически подключен в beforeFind. Я не могу копировать виртуальные поля во время выполнения, как указано в кулинарной книге. Есть ли лучший обратный вызов для динамического присоединения виртуальных полей, чтобы они включались в результаты поиска?
1 ответ
Если речь идет только о включении виртуальных полей в результаты поиска, то вы можете, например, использовать отдельный метод, который их инициализирует, и вызывать этот метод из текущих запрашиваемых моделей. beforeFind()
обратный вызов, что-то вроде:
public function beforeFind($query = array())
{
if(!parent::beforeFind($query))
{
return false;
}
$this->RelatedModel->setupVirtualFields();
return true;
}
public function setupVirtualFields()
{
$user_id = $this->getCurrentUser()['id'];
$this->virtualFields = array_merge($this->virtualFields, array
(
'cost_for_user' => sprintf('CASE WHEN Inventory.user_id = %s THEN Inventory.cost ELSE Inventory.cost_for_team END', $user_id),
));
}
Вы также можете сделать это немного более общим, применив его ко всем моделям и ассоциациям, например, в AppModel::beforeFind()
обратный вызов или использование поведения:
public function beforeFind($query)
{
if(!parent::beforeFind($query))
{
return false;
}
$this->_setupVirtualFields($this);
foreach(array_keys($this->getAssociated()) as $modelName)
{
$this->_setupVirtualFields($this->{$modelName});
}
return true;
}
protected function _setupVirtualFields(Model $model)
{
$method = 'setupVirtualFields';
if(method_exists($model, $method) && is_callable(array($model, $method)))
{
$model->setupVirtualFields();
}
}