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

时间:2014-01-03 23:32:19

标签: laravel laravel-4 eloquent

在Eloquent中,我想生成此查询:

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

但我似乎正在生成此查询:

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

这是我的实现和代码:

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

Model包含:

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

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

感谢您的帮助。我搜索过包括Advanced Wheres在内的文档无济于事。

5 个答案:

答案 0 :(得分:19)

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

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

答案 1 :(得分:10)

查看编辑以获得最终答案

优于原始,使用或者有封闭的地方:

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

非常不幸的事情(以及我在这篇文章中的结果)是闭包中使用的第二个$查询是\ Illuminate \ Database \ Query \ Builder的实例,而不是\ Illuminate \ Database \ Eloquent \ Builder - 这意味着您无法在该闭包内使用模型范围,因为Query \ Builder实例没有对模型的引用。

尽管如此,我仍然认为这更像ORM并且作为开发人员非常有用。

修改

花了一段时间才弄明白,但是如果你想要使用你的范围,这也会有效:

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

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

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

答案 2 :(得分:6)

我参加派对有点晚了,但是最合乎逻辑的方法是将这个地方包裹在一个Closure中吗?

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

答案 3 :(得分:3)

你测试过whereRaw()吗?

所以你的功能应该是这样的:

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

PS。这是未经测试的

答案 4 :(得分:1)

要包装查询,您可以执行以下操作:

$builder->where(function ($query) {
    $query->where('gender', 'Male')
        ->where('age', '>=', 18);
})->orWhere(function($query) {
    $query->where('gender', 'Female')
        ->where('age', '>=', 65);   
})

它将输出以下查询:

WHERE (gender = 'Male' and age >= 18) or (gender = 'Female' and age >= 65)