如果表中的关系存在,则从查询中排除结果

时间:2016-08-09 18:06:19

标签: laravel laravel-5 eloquent laravel-5.2

我有两张桌子:

posts表:

id | user_id | message
----------------------
 1 |      24 | hello
 2 |      96 | world
...

posts_seen表:

id | user_id | post_id
----------------------
 1 |      24 |       2
 2 |      96 |       1

第二个表格posts_seen,只是跟踪哪些帖子已被"看到"用户(或阅读)。例如,用户#24已经看过帖子#2。

在我的Post.php模型中,我有这个:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $table = 'posts';

    public function seen()
    {
        return $this->hasOne('App\Models\PostSeen');
    }
}

但是,当我查询帖子时,我想要排除用户已经看过的帖子。现在,我只有这个:

$posts = Post::with('seen')
    ->get();

我想修改这个,这样,如果我是用户#24,查询不应该返回#2,因为我已经看过了。

我该怎么做?

2 个答案:

答案 0 :(得分:2)

您应该在查询构建器中使用方法whereNotExists,如下所示:

$posts = Post::whereNotExists(function ($query) {
    $query->select(DB::raw(1))
          ->from('posts_seen')
          ->whereRaw('posts_seen.user_id = posts.user_id');
})
->get();

请注意,我还假设您不再需要seen关系。如果我错了,你可以再次拨打with

答案 1 :(得分:0)

你可以这样做:
首先选择由user_id

标识的用户看到的帖子ID
$posts_seen = PostSeen::where('user_id',$user_id)->get()->lists('post_id');

然后使用$posts_seen方法选择whereNotIn()中排除帖子ID 的所有帖子。

  

whereNotIn 方法验证给定列的值不是   包含在给定数组中:

Post::whereNotIn('id',$posts_seen)->get();