Skip to content
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

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
Expand Up @@ -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;
}
Expand Down
14 changes: 10 additions & 4 deletions lib/Relationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'))
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Up @@ -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))
Expand Down Expand Up @@ -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());
Expand All @@ -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
*/
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -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);

Expand Down