【问题标题】:Laravel Eloquent: Get record that contains two specific relationsLaravel Eloquent:获取包含两个特定关系的记录
【发布时间】:2015-07-23 10:01:29
【问题描述】:

我有一个项目,用户可以在其中创建与其他用户的对话。对话可以belongsToMany用户,用户可以belongsToMany对话。

我现在需要获取两个特定用户参与的对话。

我尝试了使用whereIn 的解决方案组合,并尝试了以下方法:

$c = Conversation::whereHas('users', function($q)
     {
         $q->whereIn('user_id', array(1,3));
     })
    ->get();

这里的问题是whereIn('user_id', [1,3]) 获取包含 EITHER 1 或 3 的记录。我需要它返回包含 BOTH 1 和 3 的记录。

对话模型

class Conversation extends Model {

    public function users(){
        return $this->belongsToMany('App\User');
    }
}

用户模型

class User extends Model {

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

}

表格

对话:

标识 |主题

conversation_user:

标识 |用户 ID |对话ID

conversation_user 表中的数据

【问题讨论】:

  • 您确定用户 1 和 3 不属于您的所有对话吗?你已经尝试过的东西在我看来是正确的。
  • 是的,为了清楚起见,我在表格中包含了当前数据的屏幕截图。

标签: php laravel laravel-5 eloquent has-and-belongs-to-many


【解决方案1】:

您的最新编辑更有意义,这实际上是一个非常简单的修复。 whereHas 需要两个额外的参数来查找计数。

$users = [1, 3];   

$c = Conversation::whereHas('users', function($q) use ($users)
{
    $q->whereIn('user_id', $users);
}, '>', count($users) )
->get();

这将获取用户 1 和 3 参与的所有对话,即使还有其他用户参与了这些对话。如果您只想与用户 1 和 3 进行对话,请将 > 更改为 =

编辑:我刚刚意识到您的数据透视表有一个 id 列。如果您的数据透视表将有重复项,此方法可能不起作用。例如,如果您有两次 user_id 为 1 且两次都具有相同的 conversation_id,即使从技术上讲它只有 1 个用户,它也会返回该会话。我建议删除id 列并创建user_idconversation_id 的复合主键。如果存在重复的可能性,使用 lukasgeiter 的解决方案可能更安全。

【讨论】:

    【解决方案2】:

    您当前正在查询用户 1 和/ 3 参与的对话。要实现您想要的,您需要两个 whereHas 调用:

    $c = Conversation::whereHas('users', function($q)
         {
             $q->where('user_id', 1);
         })
         ->whereHas('users', function($q)
         {
             $q->where('user_id', 3);
         }
         ->get();
    

    如果您有两个以上的用户,请循环添加:

    $users = [1, 2, 3, 4, 5];
    $c = Conversation::query();
    foreach($users as $userId){
        $c->whereHas('users', function($q) use ($userId)
        {
            $q->where('user_id', $userId);
        });
    }
    $c = $c->get();
    

    【讨论】:

      【解决方案3】:

      希望对你有帮助……

          $userIds = array(1,3);
          $c = Conversation::whereHas('users', function($q) use ($userIds)
               {
                   $q->whereIn('user_id', $userIds);
               })
              ->get();
      

      【讨论】:

      • 感谢,别担心,我只是硬编码了 id,以减少问题中的多余代码并帮助确定问题的原因。这不会解决我的问题。
      猜你喜欢
      • 1970-01-01
      • 2021-06-04
      • 1970-01-01
      • 2016-03-25
      • 2015-06-24
      • 2020-06-02
      • 1970-01-01
      • 1970-01-01
      • 2020-11-03
      相关资源
      最近更新 更多