Laravel - 使用“whereHas”获取嵌套关系

Posted

技术标签:

【中文标题】Laravel - 使用“whereHas”获取嵌套关系【英文标题】:Laravel - Get nested relation with "whereHas" 【发布时间】:2019-11-17 16:04:23 【问题描述】:

我有三个模型PeriodPostUser

periodpostsperiod_posts 上具有 M:N 关系

postsuserviews 上具有 M:N 关系

周期模型:

class Period extends Model


    public $timestamps=false;

    public function posts()
    
        return $this->belongsToMany(Post::class);
    

后模型:

class Post extends Model

    public function periods()
    
        return $this->belongsToMany(Period::class);
    


    public function views()
    
        return $this->belongsToMany(User::class, 'views')
            ->withTimestamps();
    

用户模型:

class User extends Authenticatable

use Notifiable;



  public function views()
  
      return $this->belongsToMany(Post::class, 'views')
          ->withTimestamps();
  

查看表:

id user_id post_id

我需要获取所有periods 及其posts,其中auth user 没有看到(通过查看关系)

我尝试这样做,但没有奏效:

    $period = Period::whereHas('posts.views', function ($users) 
        $users->where('user_id', auth()->Id());
    )->get();

【问题讨论】:

所以你必须为已验证的用户获取所有时期及其看不见的帖子? views 表是否只包含看到的帖子? views 表包含 post_iduser_id ...换句话说,post 与使用 user 表的 user 有 m:n 关系 【参考方案1】:

似乎你的模型有点“混乱”,你可以用 Eloquent 得到你想要的,但你必须把逻辑分成几个部分。

例子:

// Get all user seen posts #1
$seenPosts = Auth::user()->views()->pluck('id');

// Get all user unseen posts with its period inside the collection #2
$posts = Post::whereNotIn('id',$seenPosts)->with('periods')->get(); 

【讨论】:

我有三个 m:n 关系 .. 我有两个数据透视表 viewsposts_period .. 带有句点的帖子的 M:N 关系不是一对多 好了,用前面的代码就可以搞定一切了。首先,您必须获取所有用户看到的帖子(#1)。然后你可以得到所有看不见的帖子及其句号(#2)。【参考方案2】:

可以使用whereDoesntHave,我在我的电脑上测试过,运行良好:

$post_ids = Post::whereDoesntHave('views', function($q)
    $q->where('user_id',Auth::id());
)->get()->pluck('id');
$periods = Period::whereHas('posts', function($q) use($post_ids)
    $q->whereIn('post_id',$post_ids);
)->get();
dd($periods->pluck('id'));

【讨论】:

【参考方案3】:

假设您有一个视图表模型,您可以使用视图模型来查找所有看不见的帖子。

View::where('user_id', '!=', Auth::user()->id)->groupBy('post_id')->whereHas('posts')->pluck('post_id');

【讨论】:

【参考方案4】:

我的解决方案只对一个查询做同样的事情:

Period::query()
      ->whereHas('posts', function ($query) 
        $query->whereHas('views', function ($query) 
          $query->where('users.id', '=', auth()->Id());
        , '=', 0);
    );

【讨论】:

以上是关于Laravel - 使用“whereHas”获取嵌套关系的主要内容,如果未能解决你的问题,请参考以下文章

没有收到与 whereHas Laravel 相关的数据

在 Laravel 5 中合并 'with' 和 'whereHas'

SQLSTATE[HY000] [2002] 使用 whereHas 时 laravel 中的连接被拒绝错误

如何在 whereHas laravel 中使用 groupBy

从 Laravel 5.1 升级到 Laravel 5.8 后 whereHas() 变慢

Laravel - whereHas 查询没有返回正确的记录