Skip to content

Commit db57637

Browse files
committed
[13.x] Fix eager loaded oneOfMany relationship constraints in closures
1 parent a3d63c8 commit db57637

3 files changed

Lines changed: 43 additions & 30 deletions

File tree

src/Illuminate/Database/Eloquent/Builder.php

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -945,36 +945,7 @@ protected function eagerLoadRelation(array $models, $name, Closure $constraints)
945945

946946
$relation->addEagerConstraints($models);
947947

948-
// For one-of-many relationships, we need to also apply the user's eager
949-
// load constraints to the inner subquery that determines which record
950-
// is the "latest" / "oldest". We snapshot the outer query's wheres
951-
// before and after applying constraints, then copy only the new ones.
952-
$subQuery = method_exists($relation, 'getOneOfManySubQuery')
953-
? $relation->getOneOfManySubQuery()
954-
: null;
955-
956-
if ($subQuery) {
957-
$whereCountBefore = count($relation->getQuery()->getQuery()->wheres);
958-
$bindingCountBefore = count($relation->getQuery()->getQuery()->bindings['where']);
959-
}
960-
961-
$constraints($relation);
962-
963-
if ($subQuery) {
964-
$outerWheres = $relation->getQuery()->getQuery()->wheres;
965-
$outerBindings = $relation->getQuery()->getQuery()->bindings['where'];
966-
967-
$newWheres = array_slice($outerWheres, $whereCountBefore);
968-
$newBindings = array_slice($outerBindings, $bindingCountBefore);
969-
970-
foreach ($newWheres as $where) {
971-
$subQuery->getQuery()->wheres[] = $where;
972-
}
973-
974-
foreach ($newBindings as $binding) {
975-
$subQuery->getQuery()->addBinding($binding, 'where');
976-
}
977-
}
948+
$relation->applyEagerLoadingConstraints($constraints);
978949

979950
// Once we have the results, we just match those back up to their parent models
980951
// using the relationship instance. Then we just return the finished arrays

src/Illuminate/Database/Eloquent/Relations/Concerns/CanBeOneOfMany.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,4 +329,35 @@ public function getRelationName()
329329
{
330330
return $this->relationName;
331331
}
332+
333+
/**
334+
* Apply the given constraints to the relationship.
335+
*
336+
* @param \Closure $constraints
337+
* @return void
338+
*/
339+
public function applyEagerLoadingConstraints(Closure $constraints)
340+
{
341+
$subQuery = $this->getOneOfManySubQuery();
342+
343+
if ($subQuery) {
344+
$whereCountBefore = count($this->query->getQuery()->wheres);
345+
$bindingCountBefore = count($this->query->getQuery()->bindings['where']);
346+
}
347+
348+
$constraints($this);
349+
350+
if ($subQuery) {
351+
$newWheres = array_slice($this->query->getQuery()->wheres, $whereCountBefore);
352+
$newBindings = array_slice($this->query->getQuery()->bindings['where'], $bindingCountBefore);
353+
354+
foreach ($newWheres as $where) {
355+
$subQuery->getQuery()->wheres[] = $where;
356+
}
357+
358+
foreach ($newBindings as $binding) {
359+
$subQuery->getQuery()->addBinding($binding, 'where');
360+
}
361+
}
362+
}
332363
}

src/Illuminate/Database/Eloquent/Relations/Relation.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,17 @@ public static function getMorphAlias(string $className)
522522
return array_search($className, static::$morphMap, strict: true) ?: $className;
523523
}
524524

525+
/**
526+
* Apply the given constraints to the relationship.
527+
*
528+
* @param \Closure $constraints
529+
* @return void
530+
*/
531+
public function applyEagerLoadingConstraints(Closure $constraints)
532+
{
533+
$constraints($this);
534+
}
535+
525536
/**
526537
* Handle dynamic method calls to the relationship.
527538
*

0 commit comments

Comments
 (0)