我正在尝试为我拥有的表实现“已批准”状态,这非常简单,基本上,如果行的批准列等于 1;应该检索该行,否则不应该。
问题是,现在我必须遍历整个代码库并添加一个 WHERE 语句(即函数调用),这不仅耗时而且效率低下(如果我想删除该功能等)
我怎样才能做到这一点?是否像$this->where(..)
在 Eloquent 子类的构造函数中添加一样简单?这不会影响其他 CRUD 操作吗?例如不更新未经批准的行?
您可以覆盖主查询,仅适用于Post
模型,例如
class Post extends Eloquent
{
protected static $_allowUnapprovedPosts = false;
public function newQuery()
{
$query = parent::newQuery();
if (!static::$_allowUnapprovedPosts) {
$query->where('approved', '=', 1);
} else {
static::$_allowUnapprovedPosts = false;
}
return $query;
}
// call this if you need unapproved posts as well
public static function allowUnapprovedPosts()
{
static::$_allowUnapprovedPosts = true;
return new static;
}
}
现在,只需使用任何东西,但未经批准的用户不会出现在结果中。
$approvedPosts = Post::where('title', 'like', '%Hello%');
现在,如果您需要检索所有帖子,甚至是未经批准的帖子,那么您可以使用
$approvedPosts = Post::allowUnapprovedPosts()->where('title', 'like', '%Hello%');
因为,Laravel 现在提供Global Query Scopes,利用它而不是这个 hacky 解决方案,注意这个答案的日期,它太旧了,现在有很多事情发生了变化。
// Using a local query scope
class Post extends Eloquent
{
public function scopeApproved($query)
{
return $query->where('approved', 1);
}
}
你可以像这样使用它:
$approvedPosts = Post::approved()->get();
我发现最接近的是Eloquent 查询范围。
即使它需要对我的代码进行微小的更改(前缀查询),它仍然为我提供了我正在寻找的内容,并且具有很大的灵活性。
这是一个例子:
在 Eloquent 子类中创建一个函数:
class Post extends Eloquent {
public function scopeApproved($query)
{
return $query->where('approved', '=', 1/*true*/);
}
}
然后像这样简单地使用它:
$approvedPosts = Post::approved()-><whatever_queries_you_have_here>;
完美运行。没有丑陋的重复 WHERE 函数调用。易于修改。更容易阅读(approved()
比 更有意义where('approved', '=', 1)
)
您可以根据需要使用全局范围,文档在这里:https ://laravel.com/docs/5.6/eloquent#query-scopes
很好的例子是SoftDeletingScope,它默认应用于使用SoftDeletes特征的模型上的所有查询。