Yii 通过其他模型定义与同一模型的关系

Yii Define relation to same model through other model

在我的 Yii 应用程序中,我有 2 个模型,配置文件和组。 每个配置文件都属于 Profiles.GroupID 定义的组,该组是 Groups.GroupID 的 FK。 此外,每个组都有一个经理 (Group.ManagerID),这基本上是另一个配置文件(因此,它在 table 用户中引用 user_id)。

在模型配置文件中,我想定义一个关系,以便对于给定的配置文件,我可以轻松地检索管理器。

下面是来自两个 table 的一些示例数据,代表 2 个模型配置文件、组:

Table Profiles
user_id  firstname    lastname     group_id
-------  -----------  ----------   -------  
1        John         Doe          100  
2        Walter       White        200  
3        Gus          Fring        100  
4        Biggie       Smalls       200  


Table: Groups
group_id   manager_id
-------    ---------
100        2
200        4

如有任何建议,我们将不胜感激。

我觉得是这样的(未测试):

public function getManager() {
    $this->hasOne(Profiles::className(), ['user_id' => 'manager_id'])->viaTable('{{%groups}}', ['group_id' => 'group_id']);
}

将这个函数放在 Profiles 模型中。

您可以使用关系,您必须创建两个 "BELONGS_TO""HAS_ONE" 关系,一个在 Profiles 模型中,第二个在 Groups 模型中:

例如 Profiles:

public function relations() {
    'group' => ...
}

Groups中:

public function relations() {
    'manager' => ...
}

然后你可以获得像这样的具体用户的经理$user->group->manager

但在这种情况下生成查询 两个 JOINs,如果您的表很大,这可能会很慢。

或者你可以只使用一个关系(用于获取用户组)和一个用于获取经理的查询: 在 Profiles 模型中创建 public 变量 $manager 并将其添加到您的模型规则中(f.e 在搜索中)

public $manager = null;

并覆盖方法 afterFind:

public function afterFind() {
    $this->manager = self::model()->findByAttributes('user_id' => $this->group->manager_id);
    return parent::afterFind()
}

已编辑

如果您使用第一种方法(两个关系),您可以覆盖 DataProviderSort 对象(f.e。在模型的方法 "sort" 中) :

public function search() {
        $criteria = new CDbCriteria;
        $sort = new CSort;
        $sort->defaultOrder = 'someField ASC';
        $sort->attributes = array(
            '*',
            'managerLastname' => array(
                'ASC' => 'group.manager.lastname ASC',
                'DESC' => 'group.manager.lastname DESC',
            )
        );
        // .....other criterias
        $criteria->compare('managerLastname', $this->group->manager->lastname, true); // for filtering

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'sort' => $sort
        ));
    }

并在 CGgridView 列中 add/change 列

array(
    'name'=>'managerLastname',
    'value'=>'$data->group->manager->lastName'
) // be sure that each user has manager

并在您的模型中添加 public 属性 managerLastname

谢谢。