【问题标题】:Yii1 search() by many-many relation returns only one related modelYii1 search() by many-many 关系只返回一个相关模型
【发布时间】:2019-05-07 07:38:32
【问题描述】:

我有 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。这会起作用,我可以使用这个函数来显示交易者列表,但它会产生额外的查询和额外的代码。

【问题讨论】:

    标签: php yii orm yii1.x


    【解决方案1】:

    您可以使用它来禁用急切加载:

    $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)']
    );
    

    【讨论】:

    • 第二个关系的技巧真的很聪明,我什至没有想过。谢谢!至于现在我就这样走,如果没有其他人回答,那么我会接受这个答案
    猜你喜欢
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    相关资源
    最近更新 更多