diff --git a/src/ModelFilter.php b/src/ModelFilter.php index 95056c9..2f6e9db 100644 --- a/src/ModelFilter.php +++ b/src/ModelFilter.php @@ -351,9 +351,30 @@ public function relationIsJoined($relation) */ public function getRelatedModel($relation) { + if (strpos($relation, '.') !== false) { + return $this->getNestedRelatedModel($relation); + } + return $this->query->getModel()->{$relation}()->getRelated(); } + /** + * @param $relationString + * @return QueryBuilder|\Illuminate\Database\Eloquent\Model + */ + protected function getNestedRelatedModel($relationString) + { + $parts = explode('.', $relationString); + $related = $this->query->getModel(); + + do { + $relation = array_shift($parts); + $related = $related->{$relation}()->getRelated(); + } while (! empty($parts)); + + return $related; + } + /** * Get the table name from a relationship. * diff --git a/tests/ModelFilterChildTest.php b/tests/ModelFilterChildTest.php index 7452d50..7fc66c0 100644 --- a/tests/ModelFilterChildTest.php +++ b/tests/ModelFilterChildTest.php @@ -1,13 +1,12 @@ shouldReceive('getModel')->once()->andReturn($userMock); - - $userMock->shouldReceive('clients')->once()->andReturn($hasManyMock); - - $hasManyMock->shouldReceive('getRelated')->once()->andReturn(new Client); - - $client = (new UserFilter($userQueryMock))->getRelatedModel('clients'); - - $this->assertEquals($client, new Client); + $filter = new UserFilter($this->model->newQuery()); + // Regular relation + $this->assertInstanceOf(Client::class, $filter->getRelatedModel('clients')); + // Nested relation + $this->assertInstanceOf(Location::class, $filter->getRelatedModel('clients.locations')); } public function testProvideFilter() @@ -70,6 +61,12 @@ public function testGetModelFilterClass() $this->assertEquals($this->model->getModelFilterClass(), EloquentFilter\TestClass\UserFilter::class); } + public function testRelationDotNotation() + { + $users = $this->model->filter(['client_location' => 'one'])->get(); + $this->assertEquals(1, $users->count()); + } + public function testPaginationWorksOnBelongsToMany() { if (method_exists(\Illuminate\Database\Eloquent\Relations\Relation::class, 'macro')) { @@ -130,7 +127,10 @@ protected function dbSetup() $clients = [['name' => 'one'], ['name' => 'two'], ['name' => 'three'], ['name' => 'four']]; foreach ($clients as $index => $data) { + /** @var Client $client */ $client = Client::create($data); + $client->locations()->create($data); + /** @var User $user */ $user = User::create(['name' => 'Client'.$index]); $user->clients()->save($client); $client->managers()->save($user); diff --git a/tests/classes/Client.php b/tests/classes/Client.php index fd5b582..2571b30 100644 --- a/tests/classes/Client.php +++ b/tests/classes/Client.php @@ -27,4 +27,9 @@ public function managers() { return $this->belongsToMany(User::class); } + + public function locations() + { + return $this->hasMany(Location::class); + } } diff --git a/tests/classes/Location.php b/tests/classes/Location.php new file mode 100644 index 0000000..22bcf49 --- /dev/null +++ b/tests/classes/Location.php @@ -0,0 +1,17 @@ +belongsTo(Client::class); + } +} diff --git a/tests/classes/UserFilter.php b/tests/classes/UserFilter.php index b320dd8..579a5e2 100644 --- a/tests/classes/UserFilter.php +++ b/tests/classes/UserFilter.php @@ -25,4 +25,9 @@ public function clientsSetup() { return $this; } + + public function clientLocation($location) + { + $this->related('clients.locations', 'name', $location); + } }