Question

I have some deep associations using containable and need to filter back the results. For the sake of this question, let's say we are selling cars and want to narrow the results down by features.

Car hasmany make hasmany model HABTM features

$options = array( 
    'order' => array('Car.price'),
    'contain' => array(
        'make',
        'model' => array(
            'order' => 'Model.name ASC'
        ),
        'features'
    )
);
$cars = $this->Car->find('all', $options);

How would I go about excluding all cars that don't have power windows (Features.name != power_windows).

Was it helpful?

Solution

Containable is only suitable for you to specify what models you wanted to include when fetching data, but not limiting the parent model from fetching data at all. One obvious symptom is that sometimes your parent data may have some null contained data.

So to achieve it, I think we should use joins here so you can specify condition:

$options = array(
    'order' => array('Car.price'),
    'contain' => array(
         'make',
         'model' => array(
             'order' => 'Model.name ASC'
         ),
         'features'
    ),
    'joins' => array(
         array(
             'table' => 'features',
             'alias' => 'Feature',
             'type' => 'LEFT',
             'conditions' => array(
                 'Car.id = Feature.car_id'
             )
         )
     ),
     'conditions' => array(
          'Features.name !=' => 'power_windows',
     )
);

But one drawback of this is that you might have duplicated Car due to joining. That's a separate issue ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top