Laravel 4:如何将 WHERE 条件应用于 Eloquent 类的所有查询?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18678779/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 08:23:55  来源:igfitidea点击:

Laravel 4: How to apply a WHERE condition to all queries of an Eloquent class?

phpmysqllaravellaravel-4eloquent

提问by Abdulaziz

I'm trying to implement an "approved' state for a table I have, it's pretty straightforward, basically, if the row's approve column equals 1; that row should be retrieved, otherwise it shouldn't.

我正在尝试为我拥有的表实现“已批准”状态,这非常简单,基本上,如果行的批准列等于 1;应该检索该行,否则不应该检索。

The problem is, now I have to go through the whole codebase and add a WHERE statement(i.e., function call) which is not only time consuming but also inefficient(if I ever want to remove that feature, etc.)

问题是,现在我必须遍历整个代码库并添加一个 WHERE 语句(即函数调用),这不仅耗时而且效率低下(如果我想删除该功能等)

How can I do that? Is it as easy as adding $this->where(..)inside the Eloquent child class' constructor? Wouldn't that affect other CRUD operations? such as not updating an unapproved row?

我怎样才能做到这一点?是否像$this->where(..)在 Eloquent 子类的构造函数中添加一样简单?这不会影响其他 CRUD 操作吗?例如不更新未批准的行?

采纳答案by Abdulaziz

The closest thing I found is Eloquent query scope.

我发现最接近的是Eloquent 查询范围。

Even though it requires a minor change in my code(prefixing queries) it still gives me what I'm looking with great flexibility.

尽管它需要对我的代码(前缀查询)进行微小的更改,但它仍然以极大的灵活性为我提供了我正在寻找的内容。

Here's an example:

下面是一个例子:

Create a function within the Eloquent child class:

在 Eloquent 子类中创建一个函数:

class Post extends Eloquent {

    public function scopeApproved($query)
    {
        return $query->where('approved', '=', 1/*true*/);
    }

}

Then simply use it like this:

然后简单地像这样使用它:

$approvedPosts = Post::approved()-><whatever_queries_you_have_here>;

Works perfectly. No ugly repeated WHERE function calls. easy to modify. Much easier to read(approved()makes much more sense than where('approved', '=', 1))

完美运行。没有丑陋的重复 WHERE 函数调用。易于修改。更容易阅读(approved()比 更有意义where('approved', '=', 1)

回答by The Alpha

The answer was given when there was no query scopefeature available.

当没有可用的查询范围功能时给出了答案。

You can override the main query, only for the Postmodel, like

您可以覆盖主查询,仅适用于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;
    }
}

Now, simply use anything, but unapproved users won't appear in the result.

现在,只需使用任何东西,但未经批准的用户不会出现在结果中。

$approvedPosts = Post::where('title',  'like', '%Hello%');

Now, if you need to retrieve all posts even unapproved ones then you can use

现在,如果您需要检索所有帖子甚至未经批准的帖子,那么您可以使用

$approvedPosts = Post::allowUnapprovedPosts()->where('title',  'like', '%Hello%');

Update (Using the query scope):

更新(使用查询范围):

Since, Laravel now provides Global Query Scopes, leverage that instead of this hacky solution, notice the date of this answer, it's too old and so much things changed by now.

因为,Laravel 现在提供Global Query Scopes,利用它而不是这个 hacky 解决方案,注意这个答案的日期,它太旧了,现在已经发生了很多变化。

// Using a local query scope
class Post extends Eloquent
{

    public function scopeApproved($query)
    {
        return $query->where('approved', 1);
    }
}

You can use it like:

你可以像这样使用它:

$approvedPosts = Post::approved()->get();

回答by fico7489

You can use global scopefor your need, docs for that are here : https://laravel.com/docs/5.6/eloquent#query-scopes

您可以根据需要使用全局范围,文档在这里:https: //laravel.com/docs/5.6/eloquent#query-scopes

Good example is SoftDeletingScopewhich is applied to all queries by default on models which use SoftDeletestrait.

很好的例子是SoftDeletingScope,它默认应用于使用SoftDeletes特征的模型上的所有查询。