Domanda

Why are my global belongsTo conditions defined within a model not being applied?

I'm using CakePHP v2.4.2.

In model Order.php:

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

In controller OrdersController.php:

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

In rendered view the following SQL statement is being applied:

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

I tried different conditions, but even a simple string containing true isn't being applied (while adding this condition to PartiesController.php within a $this->Order->Agent->find(); works fine:

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

leads to:

SELECT `Agent`.`id`, `Agent`.`name` FROM `zeevracht2`.`parties` AS `Agent` WHERE true;
È stato utile?

Soluzione

After collaborating on IRC I found the answer on my own question.

It seems that conditions in the belongsTo condition of a model is only applied to the JOIN when querying an Order.

I was trying to filter Party on specific roles, e.g. Agent, which is an alias of a Party with a role as agent. So the association should be conditioned with a role set as agent. Ideally, this would automatically condition any $this->Order->Agent->find() calls. But unfortunately, this is not possible due to a technical issue which is being addressed in the development of version 3 of CakePHP.

The solution is to have two types of conditions on the association: one for the JOIN and one for the association itself.

Why one for the JOIN? E.g. when a Post belongs to User, but only post.validated should be displayed.

Altri suggerimenti

If you’re trying to find the Agent that a particular Order belongs to, then you should get the record back when querying orders. So something like:

<?php
class OrdersController extends AppController {

    public function view($id) {
        $order = $this->Order->findById($id);
        pr($order); exit;
    }
}

Should yield something like:

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

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

In your question where you then make an additional model call like $this->Order->Agent->find('list');, that’s making a new query, which will fetch all agents with no conditions. The conditions key, where you pass true, will have no affect, because that’s not a condition. Conditions should be an array, like this:

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

But as I say, if your Order model belongs to your Agent model, then you should get an Agent result set back when you get your Order result set. If not, try adding the Containable behavior to your Order model:

<?php
class Order extends AppModel {

    public $actsAs = array(
        'Containable'
    );
}

Try this:

public $belongsTo = array(
...,
'Agent' => array(
    'className' => 'Party',
    'foreignKey' => false,
    'conditions' => array('joinField'=>'joinedField', ...more conditions)
),
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top