如何在关系上添加雄辩模型的条件?

iva*_*zer 4 php mysql laravel eloquent laravel-5

我想在调用with('category')时为我的Model添加where条件.我的关系是这样的:

class Post extends Model
{
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我使用此代码来显示帖子类别:

Post::where('slug', $slug)->with('category')->get();
Run Code Online (Sandbox Code Playgroud)

我想在with('category')调用时向Post Model添加where条件.我应该只posts.status== publishedwith('category')被调用时显示.

我认为return $this->belongsTo(Category::class);我应该添加我的where条件,但这不起作用:

return $this->query()->where('posts.status', 'published')->getModel()->belongsTo(User::class)
Run Code Online (Sandbox Code Playgroud)

如果调用('category'),如何为所有帖子查询添加where条件?我知道Laravel查询范围,但我认为我们可以使用更简单的方法.(也许是$this->belongsTo(Category::class))

pat*_*cus 13

使用其他查询实现关系.它们不是基本查询的一部分,并且无权修改基本查询,因此您无法在关系方法中执行此操作.

执行此操作的最佳方法是使用查询范围:

类:

class Post extends Model
{
    public function scopeWithCategory($query)
    {
        return $query->with('category')->where('status', 'published');
    }
}
Run Code Online (Sandbox Code Playgroud)

查询:

$posts = Post::where('slug', $slug)->withCategory()->get();
Run Code Online (Sandbox Code Playgroud)

编辑

根据你的评论,我想你可能问过错误的问题.您可能希望发布另一个问题,解释您已设置的内容,以及您需要执行的操作,并查看是否有任何建议.

但是,为了回答这个具体问题,我相信你应该能够使用全局查询范围来做到这一点.这与我上面的原始答案中描述的局部范围不同.

get()在Eloquent查询构建器上调用时,将应用全局查询范围.他们可以访问查询构建器对象,并可以看到已请求加载的项目.因此,您应该能够创建一个全局查询范围来检查是否category要加载,如果是,请添加status约束.

class Post extends Model
{

    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        // make sure to call the parent method
        parent::boot();

        static::addGlobalScope('checkCategory', function(\Illuminate\Database\Eloquent\Builder $builder) {
            // get the relationships that are to be eager loaded
            $eagers = $builder->getEagerLoads();

            // check if the "category" relationship is to be eager loaded.
            // if so, add in the "status" constraint.
            if (array_key_exists('category', $eagers)) {
                $builder->where('status', 'published');
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码显示了使用匿名函数添加全局范围.这样做是为了方便和清晰.我建议创建实际的范围类,如上面链接的文档中所述.