用户可以通过2个外键进行多次对话

时间:2019-08-26 17:49:21

标签: php laravel

我的应用程序的一部分是2位用户之间的私人消息。

我有一个converstations表,该表具有user1user2外键。

现在,我想在User模型中具有雄辩的功能,可以与他进行对话。但是在任何给定的会话中,用户可以是user1user2

例如,此功能仅考虑我恰好是user1的对话。

public function conversations()
{
    return $this->hasMany('App\Conversation', 'user1');
}

那我该怎么办?

2 个答案:

答案 0 :(得分:2)

您的方法建议将Conversation的用户存储在数据透视表中。因此,在您的情况下,Conversation可以拥有两个以上的用户。这将导致更简单的查询和更多的费用选择。在这种情况下,您只需要执行以下操作即可:

return $this->belongsToMany(Conversation::class);

检查docs以获得更多信息。

添加评论

如果您确实需要此表具有这两列,则人们通常会执行以下操作:

return $this->hasMany(Conversation::class, 'user1')->orWhere('user2', $this->id);

但是,由于这是orWhere,因此可能会给您带来不正确的记录。执行此查询:

select * from "conversations" where "conversations"."user1" = 1 and "conversations"."user1" is not null or "user2" = 1

但是我找到了另一种方法。 noConstraints抽象类上有一个Relation方法,所有关系类都从该方法扩展而来,该方法使您可以修改整个查询:

use Illuminate\Database\Eloquent\Relations\HasMany;

return HasMany::noConstraints(function () {
    return $this->hasMany(Conversation::class)
        ->where('user1', $this->id)
        ->orWhere('user2', $this->id);
});

这将导致查询您要查找的内容:

select * from "conversations" where "user1" = 1 or "user2" = 1

我不确定这将如何影响预先加载等。

还是建议您使用数据透视表来保持数据库/应用程序的灵活性。

答案 1 :(得分:-1)

public function conversations()
{
    if(test_for_user1_or_user2())
    { 
        return $this->hasMany(converstations ::class,'user1_id');
    }
    return $this->hasMany(converstations ::class,'user2_id');
}