laravel 如何在关系上的雄辩模型中添加 where 条件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38053832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add where condition to eloquent model on relation?
提问by ivahidmontazer
I want to add where condition to my Model when with('category') is called. My relations are like this:
我想在调用 with('category') 时向我的模型添加 where 条件。我的关系是这样的:
class Post extends Model
{
public function category()
{
return $this->belongsTo(Category::class);
}
}
Now I use this code to display post categories:
现在我使用此代码来显示帖子类别:
Post::where('slug', $slug)->with('category')->get();
I want to add where condition to Post Model when with('category')
is called. I should display only posts.status== published
if with('category')
is called.
我想在with('category')
被调用时将 where 条件添加到 Post Model 。我应该只posts.status== published
在with('category')
被调用时显示。
I think return $this->belongsTo(Category::class);
is where i should add my where condition, but this doesn't work:
我认为return $this->belongsTo(Category::class);
是我应该添加 where 条件的地方,但这不起作用:
return $this->query()->where('posts.status', 'published')->getModel()->belongsTo(User::class)
How can I add where condition to all post queries if with('category') is called?
I know Laravel query scopes, but i think there is a simpler way we can use. (perhaps on $this->belongsTo(Category::class)
)
如果调用 with('category'),如何向所有帖子查询添加 where 条件?我知道 Laravel 查询范围,但我认为我们可以使用一种更简单的方法。(也许在$this->belongsTo(Category::class)
)
回答by patricus
Relationships are implemented using additional queries. They are not part of the base query, and do not have access to modify the base query, so you cannot do this inside the relationship method.
关系是使用附加查询实现的。它们不是基本查询的一部分,并且无权修改基本查询,因此您不能在关系方法中执行此操作。
The best way to do this is with a query scope:
最好的方法是使用查询范围:
Class:
班级:
class Post extends Model
{
public function scopeWithCategory($query)
{
return $query->with('category')->where('status', 'published');
}
}
Query:
询问:
$posts = Post::where('slug', $slug)->withCategory()->get();
Edit
编辑
Based on your comment, I think you've probably asked the wrong question. You may want to post another question explaining what you have setup, and what you need to do, and see if anyone has any suggestions from there.
根据您的评论,我认为您可能问错了问题。您可能想发布另一个问题来解释您的设置以及您需要做什么,并看看是否有人有任何建议。
However, to answer this specific question, I believe you should be able to do this using a global query scope. This is different than a local scope described in my original answer above.
但是,要回答这个特定问题,我相信您应该能够使用全局查询范围来做到这一点。这与我上面的原始答案中描述的本地范围不同。
Global query scopes are applied when get()
is called on the Eloquent query builder. They have access to the query builder object, and can see the items that have been requested to be eager loaded. Due to this, you should be able to create a global query scope that checks if category
is to be eager loaded, and if so, add in the status
constraint.
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');
}
});
}
}
The code above shows adding in a global scope using an anonymous function. This was done for ease and clarity. I would suggest creating the actual scope class, as described in the documentation linked above.
上面的代码显示了使用匿名函数在全局范围内添加。这样做是为了方便和清晰。我建议创建实际的范围类,如上面链接的文档中所述。
回答by Everton Mendon?a
This should work:
这应该有效:
Post::where(['slug' => $slug, 'status' => 'published'])->with('category')->get();