Laravel Eloquent中的多个嵌套查询

时间:2018-04-12 07:20:21

标签: laravel eloquent

我有一个聊天应用,我需要使用雄辩的ORM过滤那些在群组最后一条消息中有附件[s]的用户对话。我有以下数据库表/模型:

  • 团体&用户。关系是它们之间的N-N,因此在组和用户之间有一个名为group_user的数据透视表。虽然这个表已经扩展了一些额外的字段,因此group_user现在拥有它自己的模型。
  • 消息。两组和用户之间的关系为1-N。
  • 附件。消息的关系是1-N。

此过滤的算法不是问题 - 将用户(因为我需要特定的用户组)及其组,查找所有组消息,按创建日期按降序对其进行排序,然后选择最顶层的消息。然后检查此消息是否在“附件”表中有任何记录。很明显,我确实拥有各自模型中定义的所有关系。现在我有这个代码,但它返回任何消息中包含附件的所有组。 另外,我需要按最后一条消息'created_at'日期对查询进行排序。

return $user->user_groups()->whereHas('group', function($query) {
        $query->whereHas('messages', function ($query) {
            $query->whereHas('attachments');
        });
})->with('group')->latest()->paginate($this->group->getPerPage());

编辑。

class User
{
  public function messages()
  {
    return $this->hasMany('App\Models\Message');
  }

  public function user_groups()
  {
    return $this->hasMany('App\Models\GroupUser');
  }
}

class Message
{
  public function attachments()
  {
    return $this->hasMany('App\Models\Attachment'); 
  }

  public function author()
  {
    return $this->belongsTo('App\Models\User');
  }

  public function group()
  {
    return $this->belongsTo('App\Models\Group');
  }
}

class Attachment
{
  public function message()
  {
    return $this->belongsTo('App\Models\Message');
  }
}

class GroupUser
{
  public function user()
  {
    return $this->belongsTo('App\Models\User');
  }

  public function group()
  {
    return $this->belongsTo('App\Models\Group');
  }
}

class Group()
{
  public function messages()
  {
    return $this->hasMany('App\Models\Message');
  }

  public function group_users()
  {
    return $this->hasMany('App\Models\GroupUser');
  }
}

1 个答案:

答案 0 :(得分:0)

为您的groups模型添加User关系:

public function groups() {
    return $this->belongsToMany('App\Models\Group');
}

然后试试这个:

$user->groups()
    ->select('groups.*')
    ->join('messages', function($join) {
        $join->on('groups.id', 'messages.group_id')
            ->where('created_at', function($query) {
                $query->selectRaw('max(created_at)')
                    ->from('messages')
                    ->where('group_id', DB::raw('groups.id'));
            });
    })
    ->whereExists(function($query) {
        $query->from('attachments')
            ->where('attachments.message_id', DB::raw('messages.id'));
    })
    ->orderByDesc('messages.created_at')
    ->paginate($this->group->getPerPage());