如何在find()和fieldlist中包含关联

时间:2010-10-25 08:26:30

标签: php cakephp cakephp-1.3

我想通过find(all)接收模型数据,但是用户应该只获得一组有限的表字段。这很简单:

$ret = $this->find('all',array('fields'=>array(
    'Employee.id','Employee.address_id'
)));

但是这个模型(Employees模型)也有一个belongsTo关联:

var $belongsTo = array(
    'Address' => array(
        'className' => 'Address',
        'foreignKey' => 'address_id',
        'fields' => array('Address.full_name')
    )
);

我希望Address.full_name字段也出现在我提取的数据中。但它不适用于上面的find()调用,并且在尝试此操作时抛出错误(SQL错误:1054:'字段列表'中的未知列'Address.full_name'):

'fields'=>array('Employee.id','Employee.address_id','Address.full_name')

任何人都知道如何解决这个问题?

编辑:我完全忘记了Address.full_name是一个虚拟字段。看看Cakephp生成的SQL,很明显为什么它不起作用:

SELECT
    `Employee`.`id`, `Employee`.`address_id`, `Address`.`full_name`
FROM
    `employees` AS `Employee`
    LEFT JOIN `addresses` AS `Address`
        ON (`Employee`.`address_id` = `Address`.`id`)
WHERE 1 = 1

在地址模型中,full_name的定义如下:

var $virtualFields = array(
    'full_name' => 'CONCAT_WS(" ", Address.firstname, Address.surname)'
);

那么,问题是:它是否是一个CakePHP错误,它无法在提供给find()的字段列表中包含(外国模型)虚拟字段?

3 个答案:

答案 0 :(得分:1)

不幸的是,您无法按照自己的方式使用虚拟字段。来自Cake文档中的Limitations of Virtual Fields

  

1.3中的virtualFields实现有一些限制。首先,您不能在关联模型上对条件,顺序或字段数组使用virtualField。这样做通常会导致SQL错误,因为字段不会被ORM替换。这是因为很难估计可能找到相关模型的深度。

看起来你必须使用Containable行为。

答案 1 :(得分:0)

在这种情况下,我会使用Containable行为。

确保首先在Employee模型中加载了Containable行为:

var $actsAs = array('Containable');

然后,当您尝试获取数据时,请执行以下操作:

$params = array('fields' => array('Employee.id', 'Employee.address_id'), 
    'contain' => array('Address' => array('fields' => array('Address.full_name')));
$ret = $this->find('all', $params);

有关可容纳行为的更多信息,请访问:http://book.cakephp.org/view/1323/Containable

答案 2 :(得分:0)

  

SQL错误:1054:未知列   '字段列表'中的'Address.full_name')

此错误可为您提供线索,告知您的列名称调用(可能是fullname而不是full_name),或者更有可能是您的模型定义。员工属于一个地址,但地址是否有一个或有多个员工?