If it's just about the inclusion of virtual fields in the find results, then you could for example use a separate method that initializes them, and call this method from within the currently queried models beforeFind()
callback, something like:
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),
));
}
You could also make this a little more generic by applying it to all models and associations, for example in the AppModel::beforeFind()
callback or using a behavior:
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();
}
}