Skip to content

Honor primary_key option in $belongs_to and $has_many when eager loading #578

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/Model.php
Original file line number Diff line number Diff line change
@@ -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;
}
14 changes: 10 additions & 4 deletions lib/Relationship.php
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
36 changes: 33 additions & 3 deletions test/RelationshipTest.php
Original file line number Diff line number Diff line change
@@ -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);