在我的Yii应用程序中,我有2个模型,配置文件和组。每个概要文件属于由概要文件定义的组。GroupID是Groups.GroupID的FK。此外,每个组都有一个管理器(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
如有任何建议,不胜感激。
您可以使用关系,您必须创建两个"BELONGS_TO"
和"HAS_ONE"
关系一个在Profiles
模型中,另一个在Groups
模型中:
,例如在Profiles
:
public function relations() {
'group' => ...
}
in Groups
:
public function relations() {
'manager' => ...
}
,然后你可以得到像$user->group->manager
这样的具体用户的管理器。
但是在这种情况下,使用生成两个JOINs
,如果您的表很大,这可能会很慢。
或者您可以只使用一个关系(用于获取用户组)和一个查询来获取管理器:在Profiles
模型中创建公共变量$manager
并将其添加到模型规则中(例如在搜索中)
public $manager = null;
和重写方法afterFind
:
public function afterFind() {
$this->manager = self::model()->findByAttributes('user_id' => $this->group->manager_id);
return parent::afterFind()
}
如果您使用第一个方法(两个关系),您可以覆盖您的DataProvider
的Sort
对象(例如在您的模型的"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
并在模型中添加公共属性managerLastname
。
谢谢。
我认为是这样的(未经测试):
public function getManager() {
$this->hasOne(Profiles::className(), ['user_id' => 'manager_id'])->viaTable('{{%groups}}', ['group_id' => 'group_id']);
}