链接时如何将 Laravel Eloquent ORM 查询范围括在括号中?

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

How do you wrap Laravel Eloquent ORM query scopes in parentheses when chaining?

laravellaravel-4eloquent

提问by crowsfan85

In Eloquent, I'd like to generate this query:

在 Eloquent 中,我想生成这个查询:

SELECT * FROM table WHERE a=1 AND ( b=2 OR c=3 );

But I seem to be generating this query instead:

但我似乎正在生成这个查询:

SELECT * FROM table WHERE a=1 AND b=2 OR c=3;


Here is my implementation and code:

这是我的实现和代码:

$result = Model::aIsOne()->bIsTwoOrCIsThree()->get();

Modelcontains:

Model包含:

function scopeAIsOne($query) {
    return $query->where('a', 1);
}

function scopeBIsTwoOrCIsThree($query) {
    return $query->where('b', 2)->orWhere('c', 3);
}

Thanks for any help. I've searched through the docs including Advanced Wheresto no avail.

谢谢你的帮助。我已经搜索了包括Advanced Wheres在内的文档,但无济于事。

采纳答案by raymond.idema

Did you test whereRaw()?

你测试 whereRaw() 了吗?

so your function should look like:

所以你的函数应该是这样的:

function scopeIsFeaturedOrIsBlogPost($query) {
    return $query->whereRaw('( isFeatured = "true" OR type = "blogPost" )');
}

ps. this is untested

附:这是未经测试的

回答by Martins Balodis

You can generate parentheses by passing a callback function to where().

您可以通过将回调函数传递给 来生成括号where()

Model::where('a',1)->where(function($query) {
    $query->where('b', 2)->orWhere('c',3);
})->get();

回答by Tim

SEE EDIT FOR FINAL ANSWER

请参阅编辑以获得最终答案

Better than raw, use orWhere with a closure:

比 raw 更好,使用 orWhere 带闭包:

$model = Model::whereAIsOne()->orWhere(function($query) {
    $query->where('b', 1)->where('c', 1);
})->get();

The really unfortunate thing (and the way I ended up at this post) is that the second $query used in the closure is an instance of \Illuminate\Database\Query\Builder rather than \Illuminate\Database\Eloquent\Builder - this means that you can't use the model scopes within that closure, because Query\Builder instances don't have a reference to a model.

真正不幸的事情(以及我在这篇文章中结束的方式)是闭包中使用的第二个 $query 是 \Illuminate\Database\Query\Builder 的实例而不是 \Illuminate\Database\Eloquent\Builder - 这意味着您不能在该闭包中使用模型范围,因为 Query\Builder 实例没有对模型的引用。

That said, I still think this is much more ORM-like and useful as a developer.

也就是说,我仍然认为这更像 ORM,并且作为开发人员更有用。

EDIT

编辑

Took a while to figure out, but this will work if you want to use your scopes as well:

花了一段时间才弄清楚,但是如果您也想使用示波器,这将起作用:

$model = Model::whereAIsOne()->orWhere(function($query) {
    $this->newEloquentBuilder($query)->setModel($this)->whereBIsOneAndCIsOne();
})->get();

I'm actually creating a fourth scope in my code that encompasses all of this, so the $thismight not work in this context - however, I find that scoping for my models is one of the most important parts of building a good system.

我实际上是在我的代码中创建了第四个范围,其中包含所有这些,所以$this在这种情况下可能不起作用 - 但是,我发现我的模型的范围是构建一个好的系统最重要的部分之一。

This definitely should be built into Eloquent - the engine has a good start, but so many features are missing.

这绝对应该内置到 Eloquent 中 - 引擎有一个良好的开端,但缺少很多功能。

回答by S16

I'm a little late to the party, but wouldn't the most logical way be to wrap the where in a Closure?

我参加聚会有点晚了,但最合乎逻辑的方法不是将 where 包裹在 Closure 中吗?

    Model::where('a', '=', 1)
            ->where(function($query) {
                    $query->where('b', '=', 2)
                    ->orWhere('c', '>', 3);
    })
    ->get();