CakePHP:即使在beforeFind中调用contains(),包含的行为也不适用于find()

时间:2010-10-22 08:24:20

标签: php cakephp cakephp-1.3

我的问题:链接到我的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 *。

2 个答案:

答案 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选项,它们与标准选项合并。