Commit 1a07485e by Klimov Paul Committed by Carsten Brandt

Added support for relation by array attributes

fixes #1249
parent 6a6caf71
......@@ -75,6 +75,7 @@ Yii Framework 2 Change Log
- Enh #87: Helper `yii\helpers\Security` converted into application component, cryptographic strength improved (klimov-paul)
- Enh #422: Added Support for BIT(M) data type default values in Schema (cebe)
- Enh #1160: Added $strict parameter to Inflector::camel2id() to handle consecutive uppercase chars (schmunk)
- Enh #1249: Added support for Active Record relation via array attributes (klimov-paul)
- Enh #1452: Added `Module::getInstance()` to allow accessing the module instance from anywhere within the module (qiangxue)
- Enh #2264: `CookieCollection::has()` will return false for expired or removed cookies (qiangxue)
- Enh #2435: `yii\db\IntegrityException` is now thrown on database integrity errors instead of general `yii\db\Exception` (samdark)
......
......@@ -240,8 +240,17 @@ trait ActiveRelationTrait
$link = array_values(isset($viaQuery) ? $viaQuery->link : $this->link);
foreach ($primaryModels as $i => $primaryModel) {
$key = $this->getModelKey($primaryModel, $link);
$value = isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null);
if ($this->multiple && count($link) < 2 && is_array($keys = $primaryModel->{reset($link)})) {
$value = [];
foreach ($keys as $key) {
if (isset($buckets[$key])) {
$value = array_merge($value, $buckets[$key]);
}
}
} else {
$key = $this->getModelKey($primaryModel, $link);
$value = isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null);
}
if ($primaryModel instanceof ActiveRecordInterface) {
$primaryModel->populateRelation($name, $value);
} else {
......@@ -414,7 +423,11 @@ trait ActiveRelationTrait
$attribute = reset($this->link);
foreach ($models as $model) {
if (($value = $model[$attribute]) !== null) {
$values[] = $value;
if (is_array($value)) {
$values = array_merge($values, $value);
} else {
$values[] = $value;
}
}
}
} else {
......
......@@ -6,6 +6,7 @@ use yiiunit\data\ar\sphinx\ActiveRecord;
use yiiunit\data\ar\ActiveRecord as ActiveRecordDb;
use yiiunit\data\ar\sphinx\ArticleIndex;
use yiiunit\data\ar\sphinx\ArticleDb;
use yiiunit\data\ar\sphinx\TagDb;
/**
* @group sphinx
......@@ -34,11 +35,14 @@ class ExternalActiveRelationTest extends SphinxTestCase
$this->assertEquals(1, count($article->relatedRecords));
// has many :
/*$this->assertFalse($article->isRelationPopulated('tags'));
$this->assertFalse($article->isRelationPopulated('tags'));
$tags = $article->tags;
$this->assertTrue($article->isRelationPopulated('tags'));
$this->assertEquals(3, count($tags));
$this->assertTrue($tags[0] instanceof TagDb);*/
$this->assertEquals(count($article->tag), count($tags));
$this->assertTrue($tags[0] instanceof TagDb);
foreach ($tags as $tag) {
$this->assertTrue(in_array($tag->id, $article->tag));
}
}
public function testFindEager()
......@@ -52,10 +56,20 @@ class ExternalActiveRelationTest extends SphinxTestCase
$this->assertTrue($articles[1]->source instanceof ArticleDb);
// has many :
/*$articles = ArticleIndex::find()->with('tags')->all();
$articles = ArticleIndex::find()->with('tags')->all();
$this->assertEquals(2, count($articles));
$this->assertTrue($articles[0]->isRelationPopulated('tags'));
$this->assertTrue($articles[1]->isRelationPopulated('tags'));*/
$this->assertTrue($articles[1]->isRelationPopulated('tags'));
foreach ($articles as $article) {
$this->assertTrue($article->isRelationPopulated('tags'));
$tags = $article->tags;
$this->assertEquals(count($article->tag), count($tags));
//var_dump($tags);
$this->assertTrue($tags[0] instanceof TagDb);
foreach ($tags as $tag) {
$this->assertTrue(in_array($tag->id, $article->tag));
}
}
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment