Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Associations to the Same Model in CakePHP 3

I am using cakePHP version 3.x.

When i query the MessagesTable i want to get the Users data for the the sender and the receiver of the message. I have done this many times in cakePHP 2 but i cant figure out why it isn't working in version 3.x.

i have a UsersTable and a MessagesTable.

UsersTable

$this->hasMany('Messages');

MessagesTable

$this->belongsTo('Users', [
    'foreignKey' => 'sender_id',
    'propertyName' => 'Sender',
]);
$this->belongsTo('Users', [
    'foreignKey' => 'user_id',
    'propertyName' => 'Receiver'
]);

This is the query i am using

$messages = $this->Messages->find()
        ->where(['Messages.user_id' => $this->Auth->user('id')])
        ->orwhere(['Messages.sender_id' => $this->Auth->user('id')])
        ->order(['Messages.created' => 'DESC'])
        ->contain([
            'Users.Pictures',
        ]);

I am getting the Receiver data back but not the Sender data as well. Any help would be really appreciated

like image 914
Wisd0m Avatar asked Jun 19 '15 01:06

Wisd0m


2 Answers

Your associations are wrong. If using the same model for multiple associations you need to use different aliases and the className property (just like in CakePHP 2):-

$this->belongsTo('Sender', [
    'className' => 'Users',
    'foreignKey' => 'sender_id',
    'propertyName' => 'sender',
]);
$this->belongsTo('Receiver', [
    'className' => 'Users',
    'foreignKey' => 'user_id',
    'propertyName' => 'receiver'
]);

This is described in the docs.

In your example code Receiver is overwriting the association for User so you only see the Receiver model in the results.

Your query then needs to be something like:-

$messages = $this->Messages->find()
    ->where(['Messages.user_id' => $this->Auth->user('id')])
    ->orwhere(['Messages.sender_id' => $this->Auth->user('id')])
    ->order(['Messages.created' => 'DESC'])
    ->contain([
        'Receivers' => ['Pictures'],
        'Senders' => ['Pictures']
    ]);
like image 143
drmonkeyninja Avatar answered Oct 22 '22 11:10

drmonkeyninja


Thank you for your help @drmonkeyninja. I have found what was wrong, all i needed to do was call the Users associations i defined in the MessagesTable, i feel so stupid now.

MessagesTable

$this->belongsTo('Sender', [
    'className' => 'Users',
    'foreignKey' => 'sender_id',
    'propertyName' => 'Sender',
]);
$this->belongsTo('Receiver', [
    'className' => 'Users',
    'foreignKey' => 'user_id',
    'propertyName' => 'Receiver'
]);

The query that works:

$messages = $this->Messages->find()
        ->where(['Messages.user_id' => $this->Auth->user('id')])
        ->orwhere(['Messages.sender_id' => $this->Auth->user('id')])
        ->order(['Messages.created' => 'DESC'])
        ->contain([
            'Sender',
            'Receiver'
        ])
    ;
like image 25
Wisd0m Avatar answered Oct 22 '22 13:10

Wisd0m