Commit 0fd82123 by Qiang Xue

support using anonymous function to customize relational queries.

parent 945c6e6a
...@@ -234,7 +234,7 @@ class ActiveFinder extends \yii\base\Object ...@@ -234,7 +234,7 @@ class ActiveFinder extends \yii\base\Object
/** /**
* @param JoinElement $parent * @param JoinElement $parent
* @param array|string $with * @param array|string $with
* @param array $config * @param array|\Closure $config
* @return null|JoinElement * @return null|JoinElement
* @throws \yii\db\Exception * @throws \yii\db\Exception
*/ */
......
...@@ -555,7 +555,7 @@ abstract class ActiveRecord extends Model ...@@ -555,7 +555,7 @@ abstract class ActiveRecord extends Model
* If the relation is HAS_MANY or MANY_MANY, it will return an array of objects * If the relation is HAS_MANY or MANY_MANY, it will return an array of objects
* or an empty array. * or an empty array.
* @param ActiveRelation|string $relation the relation object or the name of the relation * @param ActiveRelation|string $relation the relation object or the name of the relation
* @param array $params additional parameters that customize the query conditions as specified in the relation declaration. * @param array|\Closure $params additional parameters that customize the query conditions as specified in the relation declaration.
* @return mixed the related object(s). * @return mixed the related object(s).
* @throws Exception if the relation is not specified in [[relations()]]. * @throws Exception if the relation is not specified in [[relations()]].
*/ */
...@@ -569,8 +569,12 @@ abstract class ActiveRecord extends Model ...@@ -569,8 +569,12 @@ abstract class ActiveRecord extends Model
$relation = $md->relations[$relation]; $relation = $md->relations[$relation];
} }
$relation = clone $relation; $relation = clone $relation;
foreach ($params as $name => $value) { if ($params instanceof \Closure) {
$relation->$name = $value; call_user_func($params, $relation);
} else {
foreach ($params as $name => $value) {
$relation->$name = $value;
}
} }
$finder = new ActiveFinder($this->getDbConnection()); $finder = new ActiveFinder($this->getDbConnection());
......
...@@ -258,6 +258,14 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase ...@@ -258,6 +258,14 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
// has many and base limited // has many and base limited
$orders = Order::find()->with('items')->order('@.id')->limit(2)->all(); $orders = Order::find()->with('items')->order('@.id')->limit(2)->all();
$this->assertEquals(2, count($orders)); $this->assertEquals(2, count($orders));
$this->assertEquals(1, $orders[0]->items[0]->id);
/// customize "with" query
$orders = Order::find()->with(array('items' => function($q) {
$q->order('@.id DESC');
}))->order('@.id')->limit(2)->all();
$this->assertEquals(2, count($orders));
$this->assertEquals(2, $orders[0]->items[0]->id);
// findBySql with // findBySql with
$orders = Order::findBySql('SELECT * FROM tbl_order WHERE customer_id=2')->with('items')->all(); $orders = Order::findBySql('SELECT * FROM tbl_order WHERE customer_id=2')->with('items')->all();
...@@ -314,11 +322,13 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase ...@@ -314,11 +322,13 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
)); ));
$this->assertEquals(1, count($orders)); $this->assertEquals(1, count($orders));
$this->assertEquals(3, $orders[0]->id); $this->assertEquals(3, $orders[0]->id);
// original results are kept after customized query // original results are kept after customized query
$orders = $customer->orders; $orders = $customer->orders;
$this->assertEquals(2, count($orders)); $this->assertEquals(2, count($orders));
$this->assertEquals(2, $orders[0]->id); $this->assertEquals(2, $orders[0]->id);
$this->assertEquals(3, $orders[1]->id); $this->assertEquals(3, $orders[1]->id);
// as array // as array
$orders = $customer->orders(array( $orders = $customer->orders(array(
'asArray' => true, 'asArray' => true,
...@@ -327,5 +337,14 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase ...@@ -327,5 +337,14 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertTrue(is_array($orders[0])); $this->assertTrue(is_array($orders[0]));
$this->assertEquals(2, $orders[0]['id']); $this->assertEquals(2, $orders[0]['id']);
$this->assertEquals(3, $orders[1]['id']); $this->assertEquals(3, $orders[1]['id']);
// using anonymous function to customize query condition
$orders = $customer->orders(function($q) {
$q->order('@.id DESC')->asArray();
});
$this->assertEquals(2, count($orders));
$this->assertTrue(is_array($orders[0]));
$this->assertEquals(3, $orders[0]['id']);
$this->assertEquals(2, $orders[1]['id']);
} }
} }
\ No newline at end of file
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