Yii2: ActiveQuery "c" does not work

Circumstances

I have three models / db tables associated with 1: n each: An order has several commissions , and the commission has several commission_positions . Therefore, in the Commission_position field there is an FK field containing the commission identifier. The commission itself has an FK field containing the order identifier.

Order> Commission> Commission

Problem

What I need to do now is to select all the objects that have a certain value in the corresponding order model. The obvious solution is to use the Query-Object of CommissionPosition, which I expanded with a named scope. The named parameter is as follows:

 class CommissionPositionQuery extends ActiveQuery { /** * Named scope to filter positions of a certain alpha order id * @param integer $id the alpha order id * @return \common\models\query\CommissionPositionQuery */ public function alphaOrderId($id) { //TODO: with not working $this->with(['commission.order']); $this->andWhere(['alpha_order_id'=>$id]); return $this; } } 

The commission relation is defined on the Commission model and works. The second order relation is also defined on the commission model and works. The filtered alpha_order_id field is in the order table. Now I execute the request as follows:

 $filteredPositions = CommissionPosition::find()->alphaOrderId(17)->all(); 

The scope is called successful, and where part is used, but when I check the generated SQL, I don't see any connection statements, although I use the with method to tell yii to get the relationship together. The answer is an "unknown alpha_order_id column", which makes sense since there is no join to the linked tables. This is the generated SQL:

 SELECT * FROM `commission_position` WHERE (`alpha_order_id`=17) 

What am I missing? Is this a Yii2 bug?

+5
source share
2 answers

Found it myself. Name changes between Yii1 and Yii2 cause little confusion. To prevent other people from wasting time here, details:

Yii1

In yii 1, you join the ratio (example: commission) directly as follows:

 $query->with = 'commission' $query->together = true; 

Yii2 / difference

When calling the with method, as shown in the question, the relation was successfully added to the array with ActiveQuery . However, when executing the request, part of the connection was missing.

Decision

The with method doesn't seem to be the way to go. Instead, I used a method called joinWith with the following signature:

 public function joinWith($with, $eagerLoading = true, $joinType = 'LEFT JOIN') 

Now, as described in the answer, I defined the relation as the first argument ( 'commission.order' ) and left the rest as it is, because the default values ​​are fine. Note the default value for the second parameter. this ensures that the relationship connects directly!

Voilà ... as a result of sql contains the necessary connections. One trap should be considered, though: Reasonable bells, of course, will be handled by us! Method documentation link:

http://www.yiiframework.com/doc-2.0/yii-db-activequery.html#joinWith()-detail

+8
source

If you want to use JOIN :

 $this->joinWith(['commission.order']); 
0
source

Source: https://habr.com/ru/post/1206145/


All Articles