mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-22 01:30:23 +08:00
Fixes #1579: throw exception when the given AR relation name does not match in a case sensitive manner.
Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()`
This commit is contained in:
@@ -29,7 +29,7 @@ use yii\helpers\StringHelper;
|
|||||||
* @property mixed $oldPrimaryKey The old primary key value. An array (column name => column value) is
|
* @property mixed $oldPrimaryKey The old primary key value. An array (column name => column value) is
|
||||||
* returned if the primary key is composite. A string is returned otherwise (null will be returned if the key
|
* returned if the primary key is composite. A string is returned otherwise (null will be returned if the key
|
||||||
* value is null). This property is read-only.
|
* value is null). This property is read-only.
|
||||||
* @property array $populatedRelations An array of relation data indexed by relation names. This property is
|
* @property array $relatedRecords An array of the populated related records indexed by relation names. This property is
|
||||||
* read-only.
|
* read-only.
|
||||||
* @property mixed $primaryKey The primary key value. An array (column name => column value) is returned if
|
* @property mixed $primaryKey The primary key value. An array (column name => column value) is returned if
|
||||||
* the primary key is composite. A string is returned otherwise (null will be returned if the key value is null).
|
* the primary key is composite. A string is returned otherwise (null will be returned if the key value is null).
|
||||||
@@ -668,4 +668,4 @@ abstract class ActiveRecord extends BaseActiveRecord
|
|||||||
$transactions = $this->transactions();
|
$transactions = $this->transactions();
|
||||||
return isset($transactions[$scenario]) && ($transactions[$scenario] & $operation);
|
return isset($transactions[$scenario]) && ($transactions[$scenario] & $operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,13 @@ Yii Framework 2 Change Log
|
|||||||
- Enh #1469: ActiveRecord::find() now works with default conditions (default scope) applied by createQuery (cebe)
|
- Enh #1469: ActiveRecord::find() now works with default conditions (default scope) applied by createQuery (cebe)
|
||||||
- Enh #1523: Query conditions now allow to use the NOT operator (cebe)
|
- Enh #1523: Query conditions now allow to use the NOT operator (cebe)
|
||||||
- Enh #1552: It is now possible to use multiple bootstrap NavBar in a single page (Alex-Code)
|
- Enh #1552: It is now possible to use multiple bootstrap NavBar in a single page (Alex-Code)
|
||||||
|
- Enh #1579: throw exception when the given AR relation name does not match in a case sensitive manner (qiangxue)
|
||||||
- Enh: Added `favicon.ico` and `robots.txt` to defauly application templates (samdark)
|
- Enh: Added `favicon.ico` and `robots.txt` to defauly application templates (samdark)
|
||||||
- Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue)
|
- Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue)
|
||||||
- Enh: Support for file aliases in console command 'message' (omnilight)
|
- Enh: Support for file aliases in console command 'message' (omnilight)
|
||||||
- Enh: Sort and Paginiation can now create absolute URLs (cebe)
|
- Enh: Sort and Paginiation can now create absolute URLs (cebe)
|
||||||
- Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue)
|
- Chg: Renamed `yii\jui\Widget::clientEventsMap` to `clientEventMap` (qiangxue)
|
||||||
|
- Chg: Renamed `ActiveRecord::getPopulatedRelations()` to `getRelatedRecords()` (qiangxue)
|
||||||
- Chg: Added `yii\widgets\InputWidget::options` (qiangxue)
|
- Chg: Added `yii\widgets\InputWidget::options` (qiangxue)
|
||||||
- New #1438: [MongoDB integration](https://github.com/yiisoft/yii2-mongodb) ActiveRecord and Query (klimov-paul)
|
- New #1438: [MongoDB integration](https://github.com/yiisoft/yii2-mongodb) ActiveRecord and Query (klimov-paul)
|
||||||
- New #1393: [Codeception testing framework integration](https://github.com/yiisoft/yii2-codeception) (Ragazzo)
|
- New #1393: [Codeception testing framework integration](https://github.com/yiisoft/yii2-codeception) (Ragazzo)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ use yii\helpers\Inflector;
|
|||||||
* @property mixed $oldPrimaryKey The old primary key value. An array (column name => column value) is
|
* @property mixed $oldPrimaryKey The old primary key value. An array (column name => column value) is
|
||||||
* returned if the primary key is composite. A string is returned otherwise (null will be returned if the key
|
* returned if the primary key is composite. A string is returned otherwise (null will be returned if the key
|
||||||
* value is null). This property is read-only.
|
* value is null). This property is read-only.
|
||||||
* @property array $populatedRelations An array of relation data indexed by relation names. This property is
|
* @property array $relatedRecords An array of the populated related records indexed by relation names. This property is
|
||||||
* read-only.
|
* read-only.
|
||||||
* @property mixed $primaryKey The primary key value. An array (column name => column value) is returned if
|
* @property mixed $primaryKey The primary key value. An array (column name => column value) is returned if
|
||||||
* the primary key is composite. A string is returned otherwise (null will be returned if the key value is null).
|
* the primary key is composite. A string is returned otherwise (null will be returned if the key value is null).
|
||||||
@@ -232,6 +232,13 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
|
|||||||
}
|
}
|
||||||
$value = parent::__get($name);
|
$value = parent::__get($name);
|
||||||
if ($value instanceof ActiveRelationInterface) {
|
if ($value instanceof ActiveRelationInterface) {
|
||||||
|
if (method_exists($this, 'get' . $name)) {
|
||||||
|
$method = new \ReflectionMethod($this, 'get' . $name);
|
||||||
|
$realName = lcfirst(substr($method->getName(), 3));
|
||||||
|
if ($realName !== $name) {
|
||||||
|
throw new InvalidParamException('Relation names are case sensitive. ' . get_class($this) . " has a relation named \"$realName\" instead of \"$name\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
return $this->_related[$name] = $value->multiple ? $value->all() : $value->one();
|
return $this->_related[$name] = $value->multiple ? $value->all() : $value->one();
|
||||||
} else {
|
} else {
|
||||||
return $value;
|
return $value;
|
||||||
@@ -390,10 +397,10 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all populated relations.
|
* Returns all populated related records.
|
||||||
* @return array an array of relation data indexed by relation names.
|
* @return array an array of related records indexed by relation names.
|
||||||
*/
|
*/
|
||||||
public function getPopulatedRelations()
|
public function getRelatedRecords()
|
||||||
{
|
{
|
||||||
return $this->_related;
|
return $this->_related;
|
||||||
}
|
}
|
||||||
@@ -999,15 +1006,25 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
|
|||||||
{
|
{
|
||||||
$getter = 'get' . $name;
|
$getter = 'get' . $name;
|
||||||
try {
|
try {
|
||||||
|
// the relation could be defined in a behavior
|
||||||
$relation = $this->$getter();
|
$relation = $this->$getter();
|
||||||
if ($relation instanceof ActiveRelationInterface) {
|
|
||||||
return $relation;
|
|
||||||
} else {
|
|
||||||
throw new InvalidParamException(get_class($this) . ' has no relation named "' . $name . '".');
|
|
||||||
}
|
|
||||||
} catch (UnknownMethodException $e) {
|
} catch (UnknownMethodException $e) {
|
||||||
throw new InvalidParamException(get_class($this) . ' has no relation named "' . $name . '".', 0, $e);
|
throw new InvalidParamException(get_class($this) . ' has no relation named "' . $name . '".', 0, $e);
|
||||||
}
|
}
|
||||||
|
if (!$relation instanceof ActiveRelationInterface) {
|
||||||
|
throw new InvalidParamException(get_class($this) . ' has no relation named "' . $name . '".');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method_exists($this, $getter)) {
|
||||||
|
// relation name is case sensitive, trying to validate it when the relation is defined within this class
|
||||||
|
$method = new \ReflectionMethod($this, $getter);
|
||||||
|
$realName = lcfirst(substr($method->getName(), 3));
|
||||||
|
if ($realName !== $name) {
|
||||||
|
throw new InvalidParamException('Relation names are case sensitive. ' . get_class($this) . " has a relation named \"$realName\" instead of \"$name\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class ActiveRelationTest extends MongoDbTestCase
|
|||||||
$this->assertTrue($order->isRelationPopulated('customer'));
|
$this->assertTrue($order->isRelationPopulated('customer'));
|
||||||
$this->assertTrue($customer instanceof Customer);
|
$this->assertTrue($customer instanceof Customer);
|
||||||
$this->assertEquals((string)$customer->_id, (string)$order->customer_id);
|
$this->assertEquals((string)$customer->_id, (string)$order->customer_id);
|
||||||
$this->assertEquals(1, count($order->populatedRelations));
|
$this->assertEquals(1, count($order->relatedRecords));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFindEager()
|
public function testFindEager()
|
||||||
@@ -83,4 +83,4 @@ class ActiveRelationTest extends MongoDbTestCase
|
|||||||
$this->assertTrue($orders[1]->customer instanceof Customer);
|
$this->assertTrue($orders[1]->customer instanceof Customer);
|
||||||
$this->assertEquals((string)$orders[1]->customer->_id, (string)$orders[1]->customer_id);
|
$this->assertEquals((string)$orders[1]->customer->_id, (string)$orders[1]->customer_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class ActiveRelationTest extends SphinxTestCase
|
|||||||
$index = $article->index;
|
$index = $article->index;
|
||||||
$this->assertTrue($article->isRelationPopulated('index'));
|
$this->assertTrue($article->isRelationPopulated('index'));
|
||||||
$this->assertTrue($index instanceof ArticleIndex);
|
$this->assertTrue($index instanceof ArticleIndex);
|
||||||
$this->assertEquals(1, count($article->populatedRelations));
|
$this->assertEquals(1, count($article->relatedRecords));
|
||||||
$this->assertEquals($article->id, $index->id);
|
$this->assertEquals($article->id, $index->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,4 +42,4 @@ class ActiveRelationTest extends SphinxTestCase
|
|||||||
$this->assertTrue($articles[0]->index instanceof ArticleIndex);
|
$this->assertTrue($articles[0]->index instanceof ArticleIndex);
|
||||||
$this->assertTrue($articles[1]->index instanceof ArticleIndex);
|
$this->assertTrue($articles[1]->index instanceof ArticleIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class ExternalActiveRelationTest extends SphinxTestCase
|
|||||||
$source = $article->source;
|
$source = $article->source;
|
||||||
$this->assertTrue($article->isRelationPopulated('source'));
|
$this->assertTrue($article->isRelationPopulated('source'));
|
||||||
$this->assertTrue($source instanceof ArticleDb);
|
$this->assertTrue($source instanceof ArticleDb);
|
||||||
$this->assertEquals(1, count($article->populatedRelations));
|
$this->assertEquals(1, count($article->relatedRecords));
|
||||||
|
|
||||||
// has many :
|
// has many :
|
||||||
/*$this->assertFalse($article->isRelationPopulated('tags'));
|
/*$this->assertFalse($article->isRelationPopulated('tags'));
|
||||||
@@ -71,4 +71,4 @@ class ExternalActiveRelationTest extends SphinxTestCase
|
|||||||
->all();
|
->all();
|
||||||
$this->assertEquals(2, count($articles));
|
$this->assertEquals(2, count($articles));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -392,14 +392,14 @@ trait ActiveRecordTestTrait
|
|||||||
$orders = $customer->orders;
|
$orders = $customer->orders;
|
||||||
$this->assertTrue($customer->isRelationPopulated('orders'));
|
$this->assertTrue($customer->isRelationPopulated('orders'));
|
||||||
$this->assertEquals(2, count($orders));
|
$this->assertEquals(2, count($orders));
|
||||||
$this->assertEquals(1, count($customer->populatedRelations));
|
$this->assertEquals(1, count($customer->relatedRecords));
|
||||||
|
|
||||||
/** @var Customer $customer */
|
/** @var Customer $customer */
|
||||||
$customer = $this->callCustomerFind(2);
|
$customer = $this->callCustomerFind(2);
|
||||||
$this->assertFalse($customer->isRelationPopulated('orders'));
|
$this->assertFalse($customer->isRelationPopulated('orders'));
|
||||||
$orders = $customer->getOrders()->where(['id' => 3])->all();
|
$orders = $customer->getOrders()->where(['id' => 3])->all();
|
||||||
$this->assertFalse($customer->isRelationPopulated('orders'));
|
$this->assertFalse($customer->isRelationPopulated('orders'));
|
||||||
$this->assertEquals(0, count($customer->populatedRelations));
|
$this->assertEquals(0, count($customer->relatedRecords));
|
||||||
|
|
||||||
$this->assertEquals(1, count($orders));
|
$this->assertEquals(1, count($orders));
|
||||||
$this->assertEquals(3, $orders[0]->id);
|
$this->assertEquals(3, $orders[0]->id);
|
||||||
@@ -421,7 +421,7 @@ trait ActiveRecordTestTrait
|
|||||||
$customer = $this->callCustomerFind()->where(['id' => 1])->with('orders')->one();
|
$customer = $this->callCustomerFind()->where(['id' => 1])->with('orders')->one();
|
||||||
$this->assertTrue($customer->isRelationPopulated('orders'));
|
$this->assertTrue($customer->isRelationPopulated('orders'));
|
||||||
$this->assertEquals(1, count($customer->orders));
|
$this->assertEquals(1, count($customer->orders));
|
||||||
$this->assertEquals(1, count($customer->populatedRelations));
|
$this->assertEquals(1, count($customer->relatedRecords));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFindLazyVia()
|
public function testFindLazyVia()
|
||||||
|
|||||||
Reference in New Issue
Block a user