我的问题:链接到我的Employees
表我有一个Address
表,其中包含一个名为full_name
的虚拟字段(我猜你可以自己想象它的作用)。我添加了可包含行为和此功能
function beforeFind() {
$this->contain('Address.full_name');
}
到我的Employees模型,这样我就不必在每个控制器动作中调用$this->contain(..)
(我在每个动作中都需要full_name
字段)。但是,如果控制器操作仅执行$this->Employee->find('all')
(或read(..)
,则ID无效。相反,如果
$this->paginate();
代替$this->Employee->contain('Address.full_name');
来电之前调用$this->Employee->find('all');
。我无法想象造成这种情况的原因,因为在明确的contain(..)
调用之后,模型回调函数contain(..)
再次调用beforeFind()
,作为我插入的debug
校对进入cake / libs / models / behavior / containable.php:contains()function * cough *。答案 0 :(得分:1)
据我所知,对于紧随其后的查询操作,contains()语句只能运行一次。后续查询将需要自己的contains()语句,例如
$this->Employee->contain('Address.full_name');
$this->Employee->find('all'); //first find
// returns all of Employee + Address.full_name
$this->Employee->find('all'); //second find
// returns all of Employee + all of Address + all of any other associated tables.
我不建议在beforeFind()中使用contains(),因为它旨在修改特定的返回。在每次查询之前,它很快就会变成第二种性质,然后您可以很好地控制返回的数据。
如果您对有限回报有广泛的要求,可以在模型的关联中进行设置。
答案 1 :(得分:0)
1)你的模型beforeFind()应该接受一个param $ queryData,如果应该执行find()则返回true,如果它应该在beforeFind之前中止,则返回false。通常,beforeFind($ queryData)方法将修改$ queryData数组并返回它。
function beforeFind($queryData) {
// Modify $queryData here if you want
return $queryData
}
2)试图保持持久的$ contains有点奇怪。 Containable显然包含关联,以便获取额外/附加信息。应该在正常的find()操作中返回虚拟字段。如果要限制返回的字段,则应在模型或模型关联
中定义这些字段var $belongsTo = array(
'Employee' => array(
'className' => 'Employee',
'fields' => array('Employee.id', 'Employee.full_name'),
'conditions' => array()
)
);
Containable会为您快速重新绑定关联,但您应该通过Model关联定义默认字段/条件($ belongsTo,$ hasMany,$ hasOne等)
另一种方法是实际创建反映您尝试获取的数据的模型方法,这是一个非常基本的例子:
function activeEmployees() {
$contain = array('Address');
$conditions array('Employee.started' => '2010-09-01');
$this->find('all', array('conditions' => $conditions, 'contain' => $contain));
}
然后从控制器中调用这些方便性方法,就像找到
一样$这 - >员工 - > activeEmployees();
你也可以选择将一个参数传递给Employee :: activeEmployees();这是一组额外的$ conditions或$ contains选项,它们与标准选项合并。