diff --git a/lib/Model.php b/lib/Model.php index 99667b41f..03a01f2af 100644 --- a/lib/Model.php +++ b/lib/Model.php @@ -1291,7 +1291,9 @@ public function reload() public function __clone() { - $this->__relationships = array(); + $this->__relationships = array_map(function($rel) { + return clone($rel); + }, $this->__relationships); $this->reset_dirty(); return $this; } diff --git a/lib/Relationship.php b/lib/Relationship.php index 9846b44a4..61b80ea5e 100644 --- a/lib/Relationship.php +++ b/lib/Relationship.php @@ -291,7 +291,7 @@ protected function set_class_name($class_name) if (!has_absolute_namespace($class_name) && isset($this->options['namespace'])) { $class_name = $this->options['namespace'].'\\'.$class_name; } - + $reflection = Reflections::instance()->add($class_name)->get($class_name); if (!$reflection->isSubClassOf('ActiveRecord\\Model')) @@ -507,7 +507,7 @@ public function load(Model $model) $fk = $this->foreign_key; $this->set_keys($this->get_table()->class->getName(), true); - + $class = $this->class_name; $relation = $class::table()->get_relationship($this->through); $through_table = $relation->get_table(); @@ -604,7 +604,7 @@ public function create_association(Model $model, $attributes=array(), $guard_att public function load_eagerly($models=array(), $attributes=array(), $includes, Table $table) { $this->set_keys($table->class->name); - $this->query_and_attach_related_models_eagerly($table,$models,$attributes,$includes,$this->foreign_key, $table->pk); + $this->query_and_attach_related_models_eagerly($table,$models,$attributes,$includes,$this->foreign_key, $this->primary_key); } } @@ -685,6 +685,9 @@ public function load(Model $model) */ class BelongsTo extends AbstractRelationship { + + static protected $valid_association_options = array('primary_key'); + public function __construct($options=array()) { parent::__construct($options); @@ -695,6 +698,9 @@ public function __construct($options=array()) //infer from class_name if (!$this->foreign_key) $this->foreign_key = array(Inflector::instance()->keyify($this->class_name)); + + if (!isset($this->primary_key) && isset($this->options['primary_key'])) + $this->primary_key = is_array($this->options['primary_key']) ? $this->options['primary_key'] : array($this->options['primary_key']); } public function __get($name) @@ -727,4 +733,4 @@ public function load_eagerly($models=array(), $attributes, $includes, Table $tab { $this->query_and_attach_related_models_eagerly($table,$models,$attributes,$includes, $this->primary_key,$this->foreign_key); } -} \ No newline at end of file +} diff --git a/test/RelationshipTest.php b/test/RelationshipTest.php index 957016c65..ccea4073a 100644 --- a/test/RelationshipTest.php +++ b/test/RelationshipTest.php @@ -23,7 +23,7 @@ public function set_up($connection_name=null) Venue::$has_one = array(); Employee::$has_one = array(array('position')); Host::$has_many = array(array('events', 'order' => 'id asc')); - + foreach ($this->relationship_names as $name) { if (preg_match("/$name/", $this->getName(), $match)) @@ -80,7 +80,7 @@ public function test_has_many_basic() { $this->assert_default_has_many($this->get_relationship()); } - + public function test_eager_load_with_empty_nested_includes() { $conditions['include'] = array('events'=>array()); @@ -107,7 +107,7 @@ public function test_gh_256_eager_loading_three_levels_deep() $this->assertEquals('Yeah Yeah Yeahs',$bill_events[0]->title); } - + /** * @expectedException ActiveRecord\RelationshipException */ @@ -165,6 +165,19 @@ public function test_belongs_to_with_explicit_foreign_key() Book::$belongs_to = $old; } + public function test_belongs_to_with_explicit_primary_key() + { + $old = Book::$belongs_to; + Book::$belongs_to = array(array('explicit_author', 'class_name' => 'Author', 'primary_key' => 'parent_author_id')); + + $book = Book::find(1); + $this->assert_equals(1, $book->author_id); + $this->assert_equals(1, $book->explicit_author->parent_author_id); + $this->assert_equals(3, $book->explicit_author->author_id); + + Book::$belongs_to = $old; + } + public function test_belongs_to_with_select() { Event::$belongs_to[0]['select'] = 'id, city'; @@ -423,6 +436,23 @@ public function test_has_many_with_explicit_keys() Author::$has_many = array(array('explicit_books', 'class_name' => 'Book', 'primary_key' => 'parent_author_id', 'foreign_key' => 'secondary_author_id')); $author = Author::find(4); + $this->assert_equals(2, count($author->explicit_books)); + + foreach ($author->explicit_books as $book) + $this->assert_equals($book->secondary_author_id, $author->parent_author_id); + + $this->assert_true(strpos(ActiveRecord\Table::load('Book')->last_sql, "secondary_author_id") !== false); + Author::$has_many = $old; + } + + public function test_has_many_with_explicit_keys_and_eager_loading() + { + $old = Author::$has_many; + Author::$has_many = array(array('explicit_books', 'class_name' => 'Book', 'primary_key' => 'parent_author_id', 'foreign_key' => 'secondary_author_id')); + $author = Author::find(4, array('include' => 'explicit_books')); + + $this->assert_equals(2, count($author->explicit_books)); + foreach ($author->explicit_books as $book) $this->assert_equals($book->secondary_author_id, $author->parent_author_id);