CakePHP 3 中同一模型的多个关联

Multiple Associations to the Same Model in CakePHP 3

我使用的是 cakePHP 版本 3.x。

当我查询 MessagesTable 时,我想获取消息发送者和接收者的用户数据。我在 cakePHP 2 中做过很多次,但我无法弄清楚为什么它在版本 3.x 中不起作用。

我有一个 UsersTable 和一个 MessagesTable。

用户表

$this->hasMany('Messages');

消息表

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

这是我正在使用的查询

$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',
        ]);

我正在取回接收方数据,但也没有取回发件人数据。任何帮助将不胜感激

你的联想是错误的。如果对多个关联使用相同的模型,则需要使用不同的别名和 className 属性(就像在 CakePHP 2 中一样):-

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

这是described in the docs

在您的示例代码中,Receiver 正在覆盖 User 的关联,因此您只能在结果中看到 Receiver 模型。

您的查询需要类似于:-

$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']
    ]);

感谢@drmonkeyninja 的帮助。我发现出了什么问题,我需要做的就是调用我在 MessagesTable 中定义的用户关联,我现在觉得很愚蠢。

消息表

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

有效的查询:

$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'
        ])
    ;