From d58a121b5400b473ef843f061269284a580a1309 Mon Sep 17 00:00:00 2001 From: Dave James Miller Date: Sat, 13 Dec 2014 12:16:06 +0000 Subject: [PATCH] Fix handling of camel case relation attributes So this code correctly uses the pre-loaded relation instead of running another query: $contacts = Contact::with('emailAddresses')->get(); $email_addresses = $contact[0]->email_addresses; --- src/Illuminate/Database/Eloquent/Model.php | 15 +++++----- tests/Database/DatabaseEloquentModelTest.php | 31 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Model.php b/src/Illuminate/Database/Eloquent/Model.php index e4918d907518..f41d4e29023d 100755 --- a/src/Illuminate/Database/Eloquent/Model.php +++ b/src/Illuminate/Database/Eloquent/Model.php @@ -2397,19 +2397,19 @@ public function getAttribute($key) // If the key already exists in the relationships array, it just means the // relationship has already been loaded, so we'll just return it out of // here because there is no need to query within the relations twice. - if (array_key_exists($key, $this->relations)) + $camelKey = camel_case($key); + + if (array_key_exists($camelKey, $this->relations)) { - return $this->relations[$key]; + return $this->relations[$camelKey]; } // If the "attribute" exists as a method on the model, we will just assume // it is a relationship and will load and return results from the query // and hydrate the relationship's value on the "relationships" array. - $camelKey = camel_case($key); - if (method_exists($this, $camelKey)) { - return $this->getRelationshipFromMethod($key, $camelKey); + return $this->getRelationshipFromMethod($camelKey); } } @@ -2460,14 +2460,13 @@ protected function getAttributeFromArray($key) * Get a relationship value from a method. * * @param string $key - * @param string $camelKey * @return mixed * * @throws \LogicException */ - protected function getRelationshipFromMethod($key, $camelKey) + protected function getRelationshipFromMethod($key) { - $relations = $this->$camelKey(); + $relations = $this->$key(); if ( ! $relations instanceof Relation) { diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index 10fca60c03f7..883511f73696 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -842,6 +842,30 @@ public function testGetModelAttributeMethodThrowsExceptionIfNotRelation() } + public function testGetRelationAttributeReturnsSameCollectionEachTime() + { + $model = new EloquentModelWithHasManyRelation; + + $data = array(array('name' => 'Taylor'), array('name' => 'Otwell')); + $collection = EloquentModelStub::hydrate($data); + + $model->setRelation('testRelation', $collection); + $this->assertSame($collection, $model->testRelation); + } + + + public function testGetRelationAttributeReturnsSameCollectionEachTimeWithCamelCase() + { + $model = new EloquentModelWithHasManyRelation; + + $data = array(array('name' => 'Taylor'), array('name' => 'Otwell')); + $collection = EloquentModelStub::hydrate($data); + + $model->setRelation('testRelation', $collection); + $this->assertSame($collection, $model->test_relation); + } + + public function testModelIsBootedOnUnserialize() { $model = new EloquentModelBootingTestStub; @@ -1117,3 +1141,10 @@ public function getIsAdminAttribute() return 'admin'; } } + +class EloquentModelWithHasManyRelation extends Illuminate\Database\Eloquent\Model { + public function testRelation() + { + return $this->hasMany('EloquentModelStub'); + } +}