1

我目前正在附加一个虚拟字段,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_for_user在 beforeFind 中是动态附加的,因此我无法在运行时使用cookbook中建议的方法复制虚拟字段。是否有更好的回调来动态附加虚拟字段,以便包含在包含结果中?

4

1 回答 1

2

如果只是在查找结果中包含虚拟字段,那么您可以例如使用一个单独的方法来初始化它们,并从当前查询的模型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();
    }
}
于 2013-10-19T10:50:28.157 回答