diff --git a/framework/yii/db/ActiveQuery.php b/framework/yii/db/ActiveQuery.php index 8ae6c4a..e7e76cb 100644 --- a/framework/yii/db/ActiveQuery.php +++ b/framework/yii/db/ActiveQuery.php @@ -247,20 +247,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface $with = []; } - if (!empty($with)) { - $this->with = []; - foreach ($with as $name => $value) { - if (is_integer($name)) { - // repeating relation is fine as ActiveQueryTrait::normalizeRelations() handle it well - $this->with[] = $value; - } elseif (!isset($this->with[$name])) { - // with() takes precedence over joinWith() when both specify the same relation with callback - $this->with[$name] = $value; - } - } - } - - return $this; + return $this->with($with); } /** diff --git a/framework/yii/db/ActiveQueryTrait.php b/framework/yii/db/ActiveQueryTrait.php index 79bac78..465c1f3 100644 --- a/framework/yii/db/ActiveQueryTrait.php +++ b/framework/yii/db/ActiveQueryTrait.php @@ -93,15 +93,37 @@ trait ActiveQueryTrait * ])->all(); * ~~~ * + * You can call `with()` multiple times. Each call will add relations to the existing ones. + * For example, the following two statements are equivalent: + * + * ~~~ + * Customer::find()->with('orders', 'country')->all(); + * Customer::find()->with('orders')->with('country')->all(); + * ~~~ + * * @return static the query object itself */ public function with() { - $this->with = func_get_args(); - if (isset($this->with[0]) && is_array($this->with[0])) { + $with = func_get_args(); + if (isset($with[0]) && is_array($with[0])) { // the parameter is given as an array - $this->with = $this->with[0]; + $with = $with[0]; } + + if (empty($this->with)) { + $this->with = $with; + } elseif (!empty($with)) { + foreach ($with as $name => $value) { + if (is_integer($name)) { + // repeating relation is fine as normalizeRelations() handle it well + $this->with[] = $value; + } else { + $this->with[$name] = $value; + } + } + } + return $this; } diff --git a/tests/unit/framework/ar/ActiveRecordTestTrait.php b/tests/unit/framework/ar/ActiveRecordTestTrait.php index 43cb52a..be4a40f 100644 --- a/tests/unit/framework/ar/ActiveRecordTestTrait.php +++ b/tests/unit/framework/ar/ActiveRecordTestTrait.php @@ -422,6 +422,16 @@ trait ActiveRecordTestTrait $this->assertTrue($customer->isRelationPopulated('orders')); $this->assertEquals(1, count($customer->orders)); $this->assertEquals(1, count($customer->relatedRecords)); + + // multiple with() calls + $orders = $this->callOrderFind()->with('customer', 'items')->all(); + $this->assertEquals(3, count($orders)); + $this->assertTrue($orders[0]->isRelationPopulated('customer')); + $this->assertTrue($orders[0]->isRelationPopulated('items')); + $orders = $this->callOrderFind()->with('customer')->with('items')->all(); + $this->assertEquals(3, count($orders)); + $this->assertTrue($orders[0]->isRelationPopulated('customer')); + $this->assertTrue($orders[0]->isRelationPopulated('items')); } public function testFindLazyVia()