diff --git a/src/Illuminate/Database/Eloquent/Relations/Concerns/CanBeOneOfMany.php b/src/Illuminate/Database/Eloquent/Relations/Concerns/CanBeOneOfMany.php index 800999f86c78..513af5608563 100644 --- a/src/Illuminate/Database/Eloquent/Relations/Concerns/CanBeOneOfMany.php +++ b/src/Illuminate/Database/Eloquent/Relations/Concerns/CanBeOneOfMany.php @@ -329,4 +329,24 @@ public function getRelationName() { return $this->relationName; } + + /** + * Handle dynamic method calls to the relationship. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if (static::hasMacro($method)) { + return $this->macroCall($method, $parameters); + } + + $query = $this->isOneOfMany() && (str_starts_with($method, 'where') || str_starts_with($method, 'orWhere')) + ? $this->getOneOfManySubQuery() + : $this->query; + + return $this->forwardDecoratedCallTo($query, $method, $parameters); + } } diff --git a/tests/Database/DatabaseEloquentHasOneOfManyTest.php b/tests/Database/DatabaseEloquentHasOneOfManyTest.php index c1925e7ec8d2..e6f8e7c4ff34 100755 --- a/tests/Database/DatabaseEloquentHasOneOfManyTest.php +++ b/tests/Database/DatabaseEloquentHasOneOfManyTest.php @@ -229,7 +229,8 @@ public function testItGetsWithConstraintsCorrectResults() $user->logins()->create(); $result = $user->latest_login()->whereKey($previousLogin->getKey())->getResults(); - $this->assertNull($result); + $this->assertNotNull($result); + $this->assertSame($previousLogin->id, $result->id); } public function testItEagerLoadsCorrectModels() @@ -314,7 +315,7 @@ public function testExists() $previousLogin = $user->logins()->create(); $latestLogin = $user->logins()->create(); - $this->assertFalse($user->latest_login()->whereKey($previousLogin->getKey())->exists()); + $this->assertTrue($user->latest_login()->whereKey($previousLogin->getKey())->exists()); $this->assertTrue($user->latest_login()->whereKey($latestLogin->getKey())->exists()); } @@ -349,7 +350,8 @@ public function testGet() $this->assertSame($latestLogin->id, $latestLogins->first()->id); $latestLogins = $user->latest_login()->whereKey($previousLogin->getKey())->get(); - $this->assertCount(0, $latestLogins); + $this->assertCount(1, $latestLogins); + $this->assertSame($previousLogin->id, $latestLogins->first()->id); } public function testCount() @@ -437,6 +439,21 @@ public function testEagerLoadingWithMultipleAggregates() $this->assertSame($user2Price->id, $users[1]->price->id); } + public function testEagerLoadingWithConstraintsAppliesToSubQuery() + { + $user = HasOneOfManyTestUser::create(); + $user->logins()->create(); // ID 1 + $login2 = $user->logins()->create(); // ID 2 + $user->logins()->create(); // ID 3 + + $users = HasOneOfManyTestUser::with(['latest_login' => function ($q) { + $q->where('logins.id', '<', 3); + }])->get(); + + $this->assertNotNull($users[0]->latest_login); + $this->assertSame($login2->id, $users[0]->latest_login->id); + } + public function testWithExists() { $user = HasOneOfManyTestUser::create();