全局归属到未应用的模型中定义的条件(CakePHP v2.4.2)


Global belongsTo conditions defined in model not being applied (CakePHP v2.4.2)

为什么在模型中定义的全局belongsTo条件没有应用

我使用的是CakePHP v2.4.2。

Order.php:模型中

public $belongsTo = array(
...,
'Agent' => array(
    'className' => 'Party',
    'foreignKey' => 'agent_id',
    'conditions' => array(...)
),
...

在控制器中OrdersController.php:

$agents = $this->Order->Agent->find('list');

在渲染视图中,正在应用以下SQL语句

SELECT `Agent`.`id`, `Agent`.`name` FROM `zeevracht2`.`parties` AS `Agent` WHERE 1 = 1;

我尝试了不同的条件,但即使是包含true的简单字符串也没有被应用(而在$this->Order->Agent->find();中将此条件添加到PartiesController.php也很好:

$agents = $this->Order->Agent->find('list', array(
    'conditions' => array('true')
));

导致:

SELECT `Agent`.`id`, `Agent`.`name` FROM `zeevracht2`.`parties` AS `Agent` WHERE true;

在IRC上合作后,我找到了自己问题的答案。

在查询Order时,模型的belongsTo条件中的条件似乎仅应用于JOIN

我试图在特定角色上筛选Party,例如Agent,它是角色为代理的Party的别名。因此,关联应该以角色集作为代理为条件。理想情况下,这将自动调节任何$this->Order->Agent->find()调用。但不幸的是,这是不可能的,因为CakePHP版本3的开发中正在解决一个技术问题。

解决方案是在关联上有两种类型的条件:一种用于JOIN,另一种用于关联本身。

为什么JOIN有一个?例如,当一个Post属于User,但只应显示post.validated时。

如果您试图查找特定Order所属的Agent,则在查询订单时应返回该记录。所以类似于:

<?php
class OrdersController extends AppController {
    public function view($id) {
        $order = $this->Order->findById($id);
        pr($order); exit;
    }
}

应该产生这样的结果:

Array
(
    [Order] => Array
        (
            [id] => 83
            …
        )
    [Agent] => Array
        (
            [id] => 1
            …
        )
)

在您的问题中,然后进行一个额外的模型调用,如$this->Order->Agent->find('list');,即进行一个新的查询,该查询将无条件地获取所有代理。传递trueconditions密钥不会产生任何影响,因为这不是条件。条件应该是一个数组,如下所示:

$this->Order->Agent->find('all', array(
    'conditions' => array(
        'Agent.id' => 1
    )
));

但正如我所说,如果您的Order模型属于Agent模型,那么当您获得Order结果集时,您应该返回Agent结果集。如果没有,请尝试将可控制行为添加到Order模型中:

<?php
class Order extends AppModel {
    public $actsAs = array(
        'Containable'
    );
}

试试这个:

public $belongsTo = array(
...,
'Agent' => array(
    'className' => 'Party',
    'foreignKey' => false,
    'conditions' => array('joinField'=>'joinedField', ...more conditions)
),