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 ...@@ -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 #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 #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 #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 #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 #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) - 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 ...@@ -240,8 +240,17 @@ trait ActiveRelationTrait
$link = array_values(isset($viaQuery) ? $viaQuery->link : $this->link); $link = array_values(isset($viaQuery) ? $viaQuery->link : $this->link);
foreach ($primaryModels as $i => $primaryModel) { foreach ($primaryModels as $i => $primaryModel) {
$key = $this->getModelKey($primaryModel, $link); if ($this->multiple && count($link) < 2 && is_array($keys = $primaryModel->{reset($link)})) {
$value = isset($buckets[$key]) ? $buckets[$key] : ($this->multiple ? [] : null); $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) { if ($primaryModel instanceof ActiveRecordInterface) {
$primaryModel->populateRelation($name, $value); $primaryModel->populateRelation($name, $value);
} else { } else {
...@@ -414,7 +423,11 @@ trait ActiveRelationTrait ...@@ -414,7 +423,11 @@ trait ActiveRelationTrait
$attribute = reset($this->link); $attribute = reset($this->link);
foreach ($models as $model) { foreach ($models as $model) {
if (($value = $model[$attribute]) !== null) { if (($value = $model[$attribute]) !== null) {
$values[] = $value; if (is_array($value)) {
$values = array_merge($values, $value);
} else {
$values[] = $value;
}
} }
} }
} else { } else {
......
...@@ -6,6 +6,7 @@ use yiiunit\data\ar\sphinx\ActiveRecord; ...@@ -6,6 +6,7 @@ use yiiunit\data\ar\sphinx\ActiveRecord;
use yiiunit\data\ar\ActiveRecord as ActiveRecordDb; use yiiunit\data\ar\ActiveRecord as ActiveRecordDb;
use yiiunit\data\ar\sphinx\ArticleIndex; use yiiunit\data\ar\sphinx\ArticleIndex;
use yiiunit\data\ar\sphinx\ArticleDb; use yiiunit\data\ar\sphinx\ArticleDb;
use yiiunit\data\ar\sphinx\TagDb;
/** /**
* @group sphinx * @group sphinx
...@@ -34,11 +35,14 @@ class ExternalActiveRelationTest extends SphinxTestCase ...@@ -34,11 +35,14 @@ class ExternalActiveRelationTest extends SphinxTestCase
$this->assertEquals(1, count($article->relatedRecords)); $this->assertEquals(1, count($article->relatedRecords));
// has many : // has many :
/*$this->assertFalse($article->isRelationPopulated('tags')); $this->assertFalse($article->isRelationPopulated('tags'));
$tags = $article->tags; $tags = $article->tags;
$this->assertTrue($article->isRelationPopulated('tags')); $this->assertTrue($article->isRelationPopulated('tags'));
$this->assertEquals(3, count($tags)); $this->assertEquals(count($article->tag), count($tags));
$this->assertTrue($tags[0] instanceof TagDb);*/ $this->assertTrue($tags[0] instanceof TagDb);
foreach ($tags as $tag) {
$this->assertTrue(in_array($tag->id, $article->tag));
}
} }
public function testFindEager() public function testFindEager()
...@@ -52,10 +56,20 @@ class ExternalActiveRelationTest extends SphinxTestCase ...@@ -52,10 +56,20 @@ class ExternalActiveRelationTest extends SphinxTestCase
$this->assertTrue($articles[1]->source instanceof ArticleDb); $this->assertTrue($articles[1]->source instanceof ArticleDb);
// has many : // has many :
/*$articles = ArticleIndex::find()->with('tags')->all(); $articles = ArticleIndex::find()->with('tags')->all();
$this->assertEquals(2, count($articles)); $this->assertEquals(2, count($articles));
$this->assertTrue($articles[0]->isRelationPopulated('tags')); $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