views:

52

answers:

3

I was hoping someone with an understanding on CakePHP could shed some light on a question I've been having.

Here's my scenario, I have a User this User has a Company which in turn has many Department and many Address. If I were to get a User could I expect to have access to the Company and all models associated with that Company?

So would $user['Company']['Department'][0] or $user['Company']['Address'][0] be possible?

Which brings me back to the original question, how extensive is the linkage between models?

A: 

It's as extensive as you need/want it to be. Look into the recursive option of the find() family of methods. Also the Containable behavior. The specific references you list are possible, but directly under the user:

$user['Department'][0]

Think of it as the user having many departments through its company.

Rob Wilkerson
A: 

If you access a class/object and set "$this->recursive = -1" then it only returns the object without the dependencies!

powtac
+4  A: 

In plain-vanilla model, Cake's model linkage is determined by your models' recursive attribute. Your example model relationship looks something like this:

User
-> belongsTo Company
   -> hasMany Department
   -> hasMany Address
-> hasMany PhoneExtension

(I've added an additional relationship (User hasMany PhoneExtension) to flesh out the following explanation.)

There are three accepted values for Model::recursive: -1, 0, 1 and 2. Each value indicates to Cake's ORM a different depth to retrieve model records. I'll use $this->User->find('all') to illustrate the difference.

  • At recursive = -1, Cake retrieves only the specified model (ie. User). It parses none of the model associations.

  • At recursive = 0, Cake retrieves the specified model, and parses its belongsTo associations. $this->User->find('all') would retrieve all User records, as well as the Company record to which each User belongs.

  • At recursive = 1, Cake retrieves the specified model, and parses all of its direct associations. $this->User->find('all') would retrieve all User records, as well as the Company record to which each User belongs, and all PhoneExtension records belonging to the User.

  • At recursive = 2, Cake retrieves the specified model, parses all of its direct associations and all associations of its direct associations. $this->User->find('all') would retrieve everything in the example model relationship diagram: all User records, the Company records to which the User records belong, all PhoneExtension records belonging to the User, and all Department and Address records belonging to the Company.

Which is the very long way of saying that yes, you can achieve the results you indicate in your question, at recursive = 2.

If you wanted to go deeper than what recursive = 2 gets you, you'll have to use the Containable behaviour. Let's say that your Department model had an additional association: hasMany Group. Thus:

User
-> belongsTo Company
   -> hasMany Department
      -> hasMany Group
   -> hasMany Address
-> hasMany PhoneExtension

To retrieve everything we got with a recursive = 2 retrieval, as well as all the associated Group records, you'd construct your Model::find call like this:

$this->User->find('all', array(
    'contain' => array( 
        'PhoneExtension',
        'Company' => array(
            'Department' => array( 'Group' ),
            'Address'
        )
    )
));
Daniel Wright