Yii1 search()通过多对多关系仅返回一个相关模型

时间:2019-05-07 07:38:33

标签: php yii orm yii1.x

我有3张桌子: clientstradersclient_trader_relation

客户可以有很多交易者,而交易者可以有很多客户,所以这是一个带有“数据透视表”的多对多关系。该关系在客户端模型中定义如下:

$relations = array(
        'traders' => array(self::MANY_MANY, 'traders', 'client_trader_relation(client_id, trader_id)'),
);

现在假设在CGridView中显示所有客户的列表时,一切都可以正常工作,但是我也希望能够由特定交易者搜索客户(因此,如果其中一位交易者的ID为10,则返回该交易者客户)。

我已经在模型的search()函数中做到了这一点:

public function search()
{
    $criteria=new CDbCriteria;

    $criteria->with = 'traders';
    $criteria->together = true;
    $criteria->compare('traders.id', $this->search_trader);
}

search_trader是添加到模型和规则的附加变量,因此可以用于搜索。 在此过程中,它成功地返回了指定交易者的所有客户,结果不包含任何其他相关交易者,仅包含我要搜索的交易者。我可以理解这种行为,因为这就是生成的SQL的工作方式。

我很好奇,是否可以通过某种方式返回所有交易者而无需进行任何其他查询/功能?如果没有,那么做这种事情的正确方法是什么?到目前为止,我只能想到模型中的某些功能,例如getAllTraders(),它将手动查询与当前客户端相关的所有traders。可以,我可以使用此功能显示交易者列表,但会产生其他查询和其他代码。

1 个答案:

答案 0 :(得分:0)

您可以使用此功能禁用紧急加载:

$this->with(['traders' => ['select' => false]]);

但这将为每一行创建单独的查询,因此在GridView中有20个客户端,您将获得额外的20个查询。 AFAIK没有干净,简单的方法可以有效地做到这一点。最简单的解决方法是定义其他关系,该关系将用于使用急切的加载来获取未经过滤的交易者:

public function relations() {
    return [
        'traders' => [self::MANY_MANY, 'traders', 'client_trader_relation(client_id, trader_id)'],
        'traders2' => [self::MANY_MANY, 'traders', 'client_trader_relation(client_id, trader_id)'],
    ];
}

然后定义with设置以进行快速加载:

$this->with([
    'traders' => ['select' => false],
    'traders2',
]);

然后,您可以使用$client->traders2获取交易者的完整列表。


您也可以在relations()中临时定义此关系:

$this->getMetaData()->addRelation(
    'traders2',
    [self::MANY_MANY, 'traders', 'client_trader_relation(client_id, trader_id)']
);