Sharon
Sharon

Reputation: 3919

CakePHP - How to retrieve deeply associated data?

I have the following models:

User:

Comment:

Page:

Profile:

When I retrieve a page, I want to get the associated Comments, and for each comment I want the Profile.

My comments table has fields page_id and user_id. My profile table has user_id.

So, I assume I need to do something like

Comment belongsTo 
'Profile' => array(
        'conditions' => array('Profile.user_id' => 'Comment.user_id')
    )

but that's not working - it returns a blank profile record.

I am using CakePHP 2.0.

Upvotes: 1

Views: 4079

Answers (2)

nIcO
nIcO

Reputation: 5001

If the relations are declared correctly, all the data you need can be retrieved by searching for the desired Page. But to limit the quantity of data returned, you will probably have to use te ContainableBehavior.

PageModel:

var $actsAs = array('Containable');

PagesController:

function view($id)
{
    $this->Page->contain(array('Comment' => array('User', 'Profile')));
    $page = $this->Page->find('first', array('conditions' => array('Page.id' => $id)));
}

EDIT

Sharon, according to your question it seems that Comments are linked to Users and to Profiles. But if Profile means a "user profile", the link between Comment and User is enough and the contain should then be:

$this->Page->contain(array('Comment' => array('User' => array('Profile'))));

Upvotes: 1

Dave
Dave

Reputation: 29141

Use CakePHP's Containable behavior [link]. Basically, this allows you to pick and choose which related models you want to include in your find.

You can also specify which field(s) you want from each model, specify conditions on each...etc.

It should look something like this:

//PageModel

public $actsAs = array('Containable');

public function getPage($id=null) {
    $this->recursive = -1;  //often set to -1 in the AppModel to make -1 the default
    $this->find('all', array(
        'conditions' => array(
            'Page.id' => $id
        ),
        'contain' => array(
            'Comment' => array(
                'User' => array(
                    'Profile',
                ),
            ),
        )
    ));

}

Upvotes: 2

Related Questions