cakephp dynamic virtualfield或使用containable在查找回调之前应用
我当前正在cakephp dynamic virtualfield或使用containable在查找回调之前应用,php,cakephp,containable,cakephp-2.4,Php,Cakephp,Containable,Cakephp 2.4,我当前正在beforeFind()中附加一个虚拟字段,因为我需要在查询中插入当前用户的id。在相关模型上调用find并包含此模型包括静态定义的虚拟字段,但不包括beforeFind()中的虚拟字段。。直接在模型上调用find包括动态附加的虚拟字段 以下是我的beforeFind回调: public function beforeFind($query = array()) { $user_id = $this->getCurrentUser()['id']; $this-&
beforeFind()
中附加一个虚拟字段,因为我需要在查询中插入当前用户的id。在相关模型上调用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\u
动态附加在beforeFind中,因此我无法在运行时使用中建议的类似项复制虚拟字段。动态附加虚拟字段以便包含在包含结果中是否有更好的回调?如果只是在查找结果中包含虚拟字段,那么您可以使用单独的方法对其进行初始化,并从当前查询的模型中调用此方法beforeFind()
回调,类似于:
public function beforeFind($query = array())
{
if(!parent::beforeFind($query))
{
return false;
}
$this->RelatedModel->setupVirtualFields();
return true;
}
您还可以将其应用于所有模型和关联,例如在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();
}
}
这非常有效,谢谢。。不过有几个问题。beforeFind()不应该返回$query吗?从AppModel检查parent::beforeFind($query)有什么意义?@DevinCrossman不客气
Model::beforeFind()
需要返回$query
,只有在修改了$query
并且实际应该使用这些修改的情况下,返回true
意味着继续原始查询数据。在大多数情况下,AppModel
上不需要调用parent::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();
}
}