Reputation: 2154
In my app I have a Burger
model, a Joint
model, and a Location
model.
Joints have many Burgers, and have many Locations.
What I want to do is filter Burgers two ways: based on a rating, and also bases on whether they belong to a Joint that has a Location that matches a condition, in this case, a city.
Here's what I've tried, but she no workey:
$burgers = $this->Burger->find('all', array(
'conditions' => array('Burger.official_rating !=' => 0),
'contain' => array(
'Joint',
'Joint.Location.conditions' => array(
'Location.city' => 'Toronto'
)
),
'order' => array('Burger.official_rating DESC'),
'limit' => 10
));
Joint.Location.conditions
seems to have no effect.
Edit: now using joins, but am unsure if this is the most efficient way (notice, I had to add a Contain clause, to make sure the associated data was returned in the results).
$options['joins'] = array(
array('table' => 'joints',
'alias' => 'Joint1',
'type' => 'inner',
'conditions' => array(
'Joint1.id = Burger.joint_id'
)
),
array('table' => 'locations',
'alias' => 'Location2',
'type' => 'inner',
'conditions' => array(
'Location2.joint_id = Burger.joint_id'
)
)
);
$options['conditions'] = array(
'Location2.city' => 'Toronto',
'Burger.official_rating !=' => 0
);
$options['order'] = array(
'Burger.official_rating DESC',
);
$options['limit'] = 10;
$options['contain'] = array(
'Joint','Joint.Location'
);
$burgers = $this->Burger->find('all', $options);
Upvotes: 2
Views: 600
Reputation: 29121
Problem:
This is a very common issue people have, but is easily remedied as soon as you understand that you cannot limit the main find model based on conditions against it's contained items.
The reason you can't is because doing a contain actually creates separate queries on the tables, as opposed to JOIN, which creates a single query.
Solution:
Your best bet in this case is to use CakePHP JOINs.
In some cases (not yours), the alternate to using JOINs is to change which model you're doing the query on. If you only need one condition, then you could change the find to the model with the condition instead of the one within the contain and contain in the reverse order.
Upvotes: 2