views:

33

answers:

3

In my CakePHP application I have a model called 'Customer' which describes (unsurprisingly) an individual customer. I then have a 'Sale' model about a sale. (One customer per sale, many sales per customer). Each sale then has a 'car_id' (which maps to the 'Car' model) and an 'engine_id' (maps to 'Engine model'). Currently when I get the details of one customer, it pulls in the details of each sale associated that that customer, but I want to go one 'step' deeper and have, for each sale, the details of each car and of each engine. How do I do this?

I understand the relationships between the models, but I'm clearly missing something. My current set up is like this...

Customer: $hasMany = 'Sales';

Sale: $hasOne = array('Car', 'Engine');

Obviously the 'Car' and 'Engine' don't have a sale_id associated because they can belong to lots of different sales.

+1  A: 

Check out the Containable behavior, it should let you do everything you need: http://book.cakephp.org/view/1323/Containable

In this case, once you enable containable on your models, you can do something like this:

$this->Customer->find('first', array(
    conditions -> array(
        'id' -> $customer_id),
    contain -> array(
        'Sale' -> array(
            'Car', 'Engine'))));

You can also specify which fields and conditions you want for each model within the contain.

handsofaten
Your code won't work -- you need to enclose Sale, Car, Engine in quotes. I also think this is mostly for retrieval of data.
Travis Leleu
Thanks, added the quotes, and also I didn't have enough closing parentheses. As I understood the question, it was about data retrieval.
handsofaten
+1  A: 

As I understand it, your relationship is as follows:

Customer -> Sale -> Car -> Engine

Linear, meaning Car is NOT associated to customer except through the Sale. If this is correct, you only need to set up your relationships in each of the models so they are correctly identified:

Customer hasMany Sale
Sale belongsTo Customer
Sale hasMany Car
Car belongsTo Sale
Car hasMany Engine
Engine belongsTo Car

Then when you query the database, you can do something like:

$this->Customer->find('first', array(
     'conditions' => array('id' => $ID),
     'recursive' => 1          // or 2 depending on your need
  )
);

This will allow you to drill into the data quite easily.

Read more about it here: http://book.cakephp.org/view/73/Retrieving-Your-Data

cdburgess
Just one warning using more than 2 in recursive (even 2 is dangerous) could lead to recursion i.e. Customer hasMany Sale and Sale balongs to Customer. The better option is to use Containable behavior.
Nik
A: 

I think your model relationship (and cdburgess) is wrong. It should be like this:

Customer hasMany Sale
Sale belongsTo Customer
Car hasMany Sale
Sale belongsTo Car
Engine hasMany Sale
Sale belongsTo Engine

Then, you can use Containable behaviour to retrieve all related data:

$this->Customer->Behaviors->attach('Containable');
$this->recursive = -1;
$this->Customer->find('first', array(
    'conditions' => array('id' => $ID),
    'contain' => array('Sale' => array('Car', 'Engine'))
));
Jamal Aziz