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
/**
* @param JoinElement $parent
* @param array|string $with
* @param array $config
* @param array|\Closure $config
* @return null|JoinElement
* @throws \yii\db\Exception
*/
......
......@@ -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
* or an empty array.
* @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).
* @throws Exception if the relation is not specified in [[relations()]].
*/
......@@ -569,8 +569,12 @@ abstract class ActiveRecord extends Model
$relation = $md->relations[$relation];
}
$relation = clone $relation;
foreach ($params as $name => $value) {
$relation->$name = $value;
if ($params instanceof \Closure) {
call_user_func($params, $relation);
} else {
foreach ($params as $name => $value) {
$relation->$name = $value;
}
}
$finder = new ActiveFinder($this->getDbConnection());
......
......@@ -258,6 +258,14 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
// has many and base limited
$orders = Order::find()->with('items')->order('@.id')->limit(2)->all();
$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
$orders = Order::findBySql('SELECT * FROM tbl_order WHERE customer_id=2')->with('items')->all();
......@@ -314,11 +322,13 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
));
$this->assertEquals(1, count($orders));
$this->assertEquals(3, $orders[0]->id);
// original results are kept after customized query
$orders = $customer->orders;
$this->assertEquals(2, count($orders));
$this->assertEquals(2, $orders[0]->id);
$this->assertEquals(3, $orders[1]->id);
// as array
$orders = $customer->orders(array(
'asArray' => true,
......@@ -327,5 +337,14 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertTrue(is_array($orders[0]));
$this->assertEquals(2, $orders[0]['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