Yii1 search() by many-many relation returns 只有一个相关模型

Yii1 search() by many-many relation returns only one related model

我有 3 个 table: clientstradersclient_trader_relation

客户可以有很多交易者,而交易者可以有很多客户,所以这是一个 "pivot" table 的多对多关系。该关系在客户端模型中定义如下:

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

现在在比方说 CGridView 中显示所有客户的列表时一切正常,但我也希望能够通过特定交易者搜索客户(所以如果其中一个交易者是 id 10,那么return这个客户)。

我在模型的 search() 函数中这样做过:

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

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

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

我很好奇是否有任何方法可以 return 所有 交易者从此类搜索中进行搜索而无需进行任何额外的 queries/functions?如果不是,那么做这种事情的正确方法是什么?至于现在,我只能想到模型中的某些功能,例如 getAllTraders() 会手动查询与当前客户端相关的所有 traders 。那行得通,我可以使用此功能来显示交易者列表,但它会产生额外的查询和额外的代码。

您可以使用它来禁用预先加载:

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

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

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 获取交易者的完整列表。


您也可以定义此关系 ad-hoc 而不是 relations():

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