简体   繁体   中英

CakePHP retrieve data, associate models, containable behavior

I can't seem to figure out how the containable behavior works, or how to retrieve the data from (and based) on associated models.

I need to put the following MySQL query in the cakephp find('all') function, I know i can use the query builder for the sql syntax but I want to use find function and want to figure out how it works.

SELECT events.id, events.name FROM events, user_roles
WHERE user_roles.event_id = events.id
AND user_roles.user_id = 1

The idea is simple, in the user_roles the user_id, role_id and event_id are stored. Now I want to retrieve all events for a certain user (here user_id = 1). I tried some variations on the following:

$data = $this->Event->find('all',array(
            'contain' => array(
                'UserRole' => array(
                    'fields' => array('id'),
                    'conditions' => array(
                        'UserRole.user_id' => $this->Auth->user('id')
                    )
                )
            )
        ));

But this keeps returning all events. What I want is an array like (or any other result with the same associated data):

array(
    [0] => array(
        [Event] => array(
            'id' => 1,
            'name' => 'Event Name'
        ),
        [UserRole] => array(
            'role_id' => 2,
            'event_id'=> 1
        )
    [1] => array(
        .... etc ...
)

The following models and associations are defined

class Event extends AppModel {
    public $hasMany = array(
        'UserRole' => array(
            'className' => 'UserRole',
            'foreignKey' => 'event_id',
            'dependent' => false,
        )
    )
)

class UserRole extends AppModel {
    public $belongsTo = array(
       'Event' => array(
            'className' => 'Event',
            'foreignKey' => 'event_id'
        ),
    )
)

So how does it work ;).

Edit:

I forgot to mention that I've set in AppModel.php:

public $recursive = -1;

Containable finds the associated records for the original query. What you are doing is a find('all') on your Event model with absolutely no conditions, so it will return all Events.

Then Containable will retrieve all the UserRole records that are for the given user_id and are also associated to the Event by the event_id

If you want to only retrieve events for the given user, you could do it one of two ways

Via the Event->UserRole association and chained models:

$data = $this->Event->UserRole->find('first', array(
    'conditions' => array('UserRole.user_id' => $this->Auth->user('id'),
    'contain' => array('Event')
));

$events = $data['Event'];

or

Via your current code and then using the Hash::extract method to get the Events that match. ( Hash is a CakePHP core class)

$events = Hash::extract('/UserRole[user_id='.$this->Auth->user('id').']/..', $data);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM