我有三个模型/ db-tables与1:n相关:一个order有多个commissions,一个佣金有多个commission_positions.因此,commission_position具有包含佣金ID的FK字段.佣金本身有一个包含订单ID的FK字段.
订单>委员会> CommissionPositions
我现在需要做的是选择相关订单模型中具有特定值的所有CommissionPositions.显而易见的解决方案是使用CommissionPosition的Query-Object,我使用命名范围进行扩展.命名范围如下所示:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
该关系commission在委员会模型和工作中定义.第二种关系order是在佣金模型上定义的,也是有效的.过滤后的字段alpha_order_id位于订单表中.现在我执行这样的查询:
$filteredPositions = CommissionPosition::find()->alphaOrderId(17)->all();
Run Code Online (Sandbox Code Playgroud)
成功调用范围并使用where-part,但是当我检查生成的SQL时,我看不到连接语句,即使我使用with-method告诉yii一起获取关系.响应是'未知列alpha_order_id',这是有意义的,因为没有连接到相关表.这是生成的SQL:
SELECT * FROM `commission_position` WHERE (`alpha_order_id`=17)
Run Code Online (Sandbox Code Playgroud)
我错过了什么?这是Yii2的错误吗?
PLM*_*M57 10
自己发现了这个问题.Yii1和Yii2之间的命名变化导致一些混乱.为了防止他人在这里浪费时间的细节:
在yii 1中,您将直接加入一个关系(示例:佣金),如下所示:
$query->with = 'commission'
$query->together = true;
Run Code Online (Sandbox Code Playgroud)
当调用with问题中显示的-method时,关系被成功地添加到了with的数组中ActiveQuery.但是,在执行查询时,缺少连接部分.
似乎with-method不是要走的路.相反,我使用joinWith了以下签名调用的方法:
public function joinWith($with, $eagerLoading = true, $joinType = 'LEFT JOIN')
Run Code Online (Sandbox Code Playgroud)
现在如答案所述,我将关系定义为第一个参数('commission.order'),并将其余部分保留原样,因为默认值非常好.注意第二个参数的默认值.这可以确保关系直接加入!
Voilà...生成的sql包含所需的连接.但是要考虑一个陷阱:Ambigious column namings当然要由我们自己处理!链接到该方法的文档:
http://www.yiiframework.com/doc-2.0/yii-db-activequery.html#joinWith()-detail