Skip to content

Commit 7af1994

Browse files
[10.x] Fixes on nesting operations performed while applying scopes. (#50207)
* Add tests to emphasize the issues with nesting due to scope (nesting "or" groups but not "or not" groups and doubling first where clause negation) * Fix issues : also nest on "or not" clause, and don't repeat first where clause negation when nesting
1 parent 8d47be3 commit 7af1994

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

src/Illuminate/Database/Eloquent/Builder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,9 +1454,9 @@ protected function groupWhereSliceForScope(QueryBuilder $query, $whereSlice)
14541454
// Here we'll check if the given subset of where clauses contains any "or"
14551455
// booleans and in this case create a nested where expression. That way
14561456
// we don't add any unnecessary nesting thus keeping the query clean.
1457-
if ($whereBooleans->contains('or')) {
1457+
if ($whereBooleans->contains(fn ($logicalOperator) => str_contains($logicalOperator, 'or'))) {
14581458
$query->wheres[] = $this->createNestedWhere(
1459-
$whereSlice, $whereBooleans->first()
1459+
$whereSlice, str_replace(' not', '', $whereBooleans->first())
14601460
);
14611461
} else {
14621462
$query->wheres = array_merge($query->wheres, $whereSlice);

tests/Database/DatabaseEloquentLocalScopesTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,32 @@ public function testLocalScopesCanChained()
6161
$this->assertSame('select * from "table" where "active" = ? and "type" = ?', $query->toSql());
6262
$this->assertEquals([true, 'foo'], $query->getBindings());
6363
}
64+
65+
public function testLocalScopeNestingDoesntDoubleFirstWhereClauseNegation()
66+
{
67+
$model = new EloquentLocalScopesTestModel;
68+
$query = $model
69+
->newQuery()
70+
->whereNot('firstWhere', true)
71+
->orWhere('secondWhere', true)
72+
->active();
73+
74+
$this->assertSame('select * from "table" where (not "firstWhere" = ? or "secondWhere" = ?) and "active" = ?', $query->toSql());
75+
$this->assertEquals([true, true, true], $query->getBindings());
76+
}
77+
78+
public function testLocalScopeNestingGroupsOrNotWhereClause()
79+
{
80+
$model = new EloquentLocalScopesTestModel;
81+
$query = $model
82+
->newQuery()
83+
->where('firstWhere', true)
84+
->orWhereNot('secondWhere', true)
85+
->active();
86+
87+
$this->assertSame('select * from "table" where ("firstWhere" = ? or not "secondWhere" = ?) and "active" = ?', $query->toSql());
88+
$this->assertEquals([true, true, true], $query->getBindings());
89+
}
6490
}
6591

6692
class EloquentLocalScopesTestModel extends Model

0 commit comments

Comments
 (0)