diff --git a/src/ORM/AssociationCollection.php b/src/ORM/AssociationCollection.php index 3d3bd38db53..02d2822af7b 100644 --- a/src/ORM/AssociationCollection.php +++ b/src/ORM/AssociationCollection.php @@ -56,6 +56,30 @@ public function add($alias, Association $association) return $this->_items[strtolower($alias)] = $association; } + /** + * Creates and adds the Association object to this collection. + * + * @param string $className The name of association class. + * @param string $associated The alias for the target table. + * @param array $options List of options to configure the association definition. + * @return \Cake\ORM\Association + * @throws InvalidArgumentException + */ + public function load($className, $associated, array $options = []) + { + $options += [ + 'tableLocator' => $this->getTableLocator() + ]; + + $association = new $className($associated, $options); + if (!$association instanceof Association) { + $message = sprintf('The association must extend `%s` class, `%s` given.', Association::class, get_class($association)); + throw new InvalidArgumentException($message); + } + + return $this->add($association->getName(), $association); + } + /** * Fetch an attached association by name. * diff --git a/tests/TestCase/ORM/AssociationCollectionTest.php b/tests/TestCase/ORM/AssociationCollectionTest.php index f12afadc38e..ba485de10d6 100644 --- a/tests/TestCase/ORM/AssociationCollectionTest.php +++ b/tests/TestCase/ORM/AssociationCollectionTest.php @@ -18,6 +18,7 @@ use Cake\ORM\Association\BelongsTo; use Cake\ORM\Association\BelongsToMany; use Cake\ORM\Entity; +use Cake\ORM\Locator\LocatorInterface; use Cake\TestSuite\TestCase; /** @@ -70,6 +71,47 @@ public function testAddHasRemoveAndGet() $this->assertNull($this->associations->get('Users')); } + /** + * Test the load method. + * + * @return void + */ + public function testLoad() + { + $this->associations->load(BelongsTo::class, 'Users'); + $this->assertTrue($this->associations->has('Users')); + $this->assertInstanceOf(BelongsTo::class, $this->associations->get('Users')); + $this->assertSame($this->associations->getTableLocator(), $this->associations->get('Users')->getTableLocator()); + } + + /** + * Test the load method with custom locator. + * + * @return void + */ + public function testLoadCustomLocator() + { + $locator = $this->createMock(LocatorInterface::class); + $this->associations->load(BelongsTo::class, 'Users', [ + 'tableLocator' => $locator + ]); + $this->assertTrue($this->associations->has('Users')); + $this->assertInstanceOf(BelongsTo::class, $this->associations->get('Users')); + $this->assertSame($locator, $this->associations->get('Users')->getTableLocator()); + } + + /** + * Test load invalid class. + * + * @return void + * @expectedException InvalidArgumentException + * @expectedExceptionMessage The association must extend `Cake\ORM\Association` class, `stdClass` given. + */ + public function testLoadInvalid() + { + $this->associations->load('stdClass', 'Users'); + } + /** * Test removeAll method *