在我的Yii应用程序中,我有2个模型,个人资料和群组。 每个配置文件属于由Profiles.GroupID定义的组,它是FK到Groups.GroupID。 此外,每个组都有一个管理器(Group.ManagerID),它基本上是另一个配置文件(因此,它引用表Users中的user_id)。
在模型配置文件中,我想定义一个关系,这样,对于给定的配置文件,我可以轻松地检索管理器。
以下是来自两个表的一些示例数据,这两个表代表两个模型的个人资料,组:
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
任何建议将不胜感激。
答案 0 :(得分:0)
我认为就像这样(未经测试):
public function getManager() {
$this->hasOne(Profiles::className(), ['user_id' => 'manager_id'])->viaTable('{{%groups}}', ['group_id' => 'group_id']);
}
将此功能放在“个人档案”模型中。
答案 1 :(得分:0)
您可以使用关系,您必须在"BELONGS_TO"
模型中创建两个"HAS_ONE"
和Profiles
关系,在Groups
模型中创建第二个关系:
例如Profiles
:
public function relations() {
'group' => ...
}
Groups
中的:
public function relations() {
'manager' => ...
}
并且您可以获得具体用户的经理,例如$user->group->manager
。
但是在这种情况下会使用两个JOINs
生成查询,如果您的表很大,这可能会很慢。
或者您只能使用一个关系(用于获取用户组)和另一个用于获取经理的查询:
在Profiles
模型中创建公共变量$manager
并将其添加到模型规则中(f.e in search)
public $manager = null;
并覆盖方法afterFind
:
public function afterFind() {
$this->manager = self::model()->findByAttributes('user_id' => $this->group->manager_id);
return parent::afterFind()
}
<强> EDITED 强>
如果您使用第一种方法(两种关系),则可以覆盖Sort
的{{1}}对象(f.e。在模型的方法DataProvider
中):
"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
并在模型中添加公共属性array(
'name'=>'managerLastname',
'value'=>'$data->group->manager->lastName'
) // be sure that each user has manager
。
感谢。