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

时间:2016-06-27 12:19:38

标签: php mysql laravel laravel-5 eloquent

我希望在调用(' category')时为我的模型添加where条件。我的关系是这样的:

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

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

Post::where('slug', $slug)->with('category')->get();

我希望在调用with('category')时向Post Model添加where条件。如果调用posts.status== published,我应该只显示with('category')

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

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

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

3 个答案:

答案 0 :(得分:13)

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

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

类别:

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

查询:

$posts = Post::where('slug', $slug)->withCategory()->get();

修改

根据您的评论,我认为您可能会提出错误的问题。您可能希望发布另一个问题,说明您已设置的内容,以及您需要执行的操作,并查看是否有任何建议。

但是,要回答这个具体问题,我相信你应该能够使用global query scope来解决这个问题。这与我上面原来的答案中描述的局部范围不同。

在Eloquent查询构建器上调用get()时,将应用全局查询范围。他们可以访问查询构建器对象,并可以看到已请求加载的项目。因此,您应该能够创建一个全局查询范围来检查是否要加载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');
            }
        });
    }
}

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

答案 1 :(得分:0)

这应该有效:

Post::where(['slug' => $slug, 'status' => 'published'])->with('category')->get();

答案 2 :(得分:-3)

你必须使用withPivot()方法。

    class Post extends Model
{
    public function category()
    {
        return $this->belongsTo(Category::class)->withPivot('status');
    }
}

请参阅我的问题here