Yii:CGridView - 来自 parent-table 的两行
Yii: CGridView - two rows from parent-table
Yii: 1.1.15
直到现在我用 CGridView 做了很多 - 现在我遇到了一件简单的事情:在 CGridView 中我想显示来自 parent-table:
的两个不同行的数据
table/model: 人 (parent-table)
id name
1 Bush
2 Heineken
3 Miller
4 Gonzales
table/model: 好友 (child-table)
id friend1_id friend2_id
1 1 3
2 2 4
在模型中 Frinds.php 我有一个关系:
public function relations() {
return array(
'people' => array(self::BELONGS_TO, 'People', 'friend1_id')
}
我想在我的 CGridview 中查看 - 但我不知道如何查看:
id friend1 friend2
1 Bush Miller
2 Heineken Gonzales
所以我知道你有一个 People table 用于存储所有用户,还有一个 Friends table 用于存储两个用户之间的每一个友谊的行。
现在我猜你的网格正在获取 Friends 模型的结果吧?
你应该:
1) 在 Friends 模型中正确定义两个关系:
public function relations() {
return array(
'friend1' => array(self::BELONGS_TO, 'People', 'friend1_id'),
'friend2' => array(self::BELONGS_TO, 'People', 'friend2_id'),
);
}
2) 现在在您的 Friends 模型中添加两个新属性:
class Friends extends CActiveRecord {
public $friend1Name;
public $friend2Name;
...
3) 现在在您的网格中您可以使用这种列:
'columns' => array(
'friend1Name'=>array(
'name'=>'friend1Name',
'value'=>'$data->friend1->name',
),
'friend2Name'=>array(
'name'=>'friend2Name',
'value'=>'$data->friend2->name',
),
4) 您添加的两个属性现在没有标签,您可以通过attributeLabels自定义它:
public function attributeLabels() {
return array(
'friend1Name' => 'Friend 1 name',
'friend2Name' => 'Friend 2 name',
5) 此外,如果您调整 Friends 模型的 search() 方法,您还可以实现另外两件事:
因为你是延迟加载模型,Yii 会向数据库发出 sql 请求以获取每个朋友,如果你每页显示 10 个结果,那将是 20 个请求,要将其变成唯一一个,您可以使用 $criteria->with(),并将 friend1 和 friend2 关系与 joinType 内连接放在一起。
其次,点击网格列可以实现结果排序,为此可以在search()方法返回的CActiveDataProvider中添加排序配置,映射friend1Name和friend2Name进行排序通过它们在关系中的相应字段。
更新:补充点:
public function search() {
//... compare conditions here
/* 6) Run only one SQL query by joining tables instead of one query per every Person */
$criteria->with=array(
'friend1'=>array(
'joinType'=>'INNER JOIN',
),
'friend2'=>array(
'joinType'=>'INNER JOIN',
),
);
/* Tip: You can use with() and not use the joinType but by using it we are forcing a INNER JOIN that makes sense in this case */
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
/* 7) Apply sorting for the columns from the related tables */
'sort'=>array(
'attributes'=>array(
'*',
'friend1Name'=>array(
'asc'=>'friend1.name',
'desc'=>'friend1.name desc',
),
'friend2Name'=>array(
'asc'=>'friend2.name',
'desc'=>'friend2.name desc',
),
),
),
));
}
/* 8) Auto-fill friend1Name and friend2Name with the names from the related tables */
protected function afterFind () {
$this->friend1Name=$this->friend1->name;
$this->friend2Name=$this->friend2->name;
// Tip: Now you can use in your grid directly friend1Name instead of $data->friend1->name
parent::afterFind();
}
Yii: 1.1.15
直到现在我用 CGridView 做了很多 - 现在我遇到了一件简单的事情:在 CGridView 中我想显示来自 parent-table:
的两个不同行的数据table/model: 人 (parent-table)
id name 1 Bush 2 Heineken 3 Miller 4 Gonzales
table/model: 好友 (child-table)
id friend1_id friend2_id 1 1 3 2 2 4
在模型中 Frinds.php 我有一个关系:
public function relations() {
return array(
'people' => array(self::BELONGS_TO, 'People', 'friend1_id')
}
我想在我的 CGridview 中查看 - 但我不知道如何查看:
id friend1 friend2 1 Bush Miller 2 Heineken Gonzales
所以我知道你有一个 People table 用于存储所有用户,还有一个 Friends table 用于存储两个用户之间的每一个友谊的行。
现在我猜你的网格正在获取 Friends 模型的结果吧?
你应该:
1) 在 Friends 模型中正确定义两个关系:
public function relations() {
return array(
'friend1' => array(self::BELONGS_TO, 'People', 'friend1_id'),
'friend2' => array(self::BELONGS_TO, 'People', 'friend2_id'),
);
}
2) 现在在您的 Friends 模型中添加两个新属性:
class Friends extends CActiveRecord {
public $friend1Name;
public $friend2Name;
...
3) 现在在您的网格中您可以使用这种列:
'columns' => array(
'friend1Name'=>array(
'name'=>'friend1Name',
'value'=>'$data->friend1->name',
),
'friend2Name'=>array(
'name'=>'friend2Name',
'value'=>'$data->friend2->name',
),
4) 您添加的两个属性现在没有标签,您可以通过attributeLabels自定义它:
public function attributeLabels() {
return array(
'friend1Name' => 'Friend 1 name',
'friend2Name' => 'Friend 2 name',
5) 此外,如果您调整 Friends 模型的 search() 方法,您还可以实现另外两件事:
因为你是延迟加载模型,Yii 会向数据库发出 sql 请求以获取每个朋友,如果你每页显示 10 个结果,那将是 20 个请求,要将其变成唯一一个,您可以使用 $criteria->with(),并将 friend1 和 friend2 关系与 joinType 内连接放在一起。
其次,点击网格列可以实现结果排序,为此可以在search()方法返回的CActiveDataProvider中添加排序配置,映射friend1Name和friend2Name进行排序通过它们在关系中的相应字段。
更新:补充点:
public function search() {
//... compare conditions here
/* 6) Run only one SQL query by joining tables instead of one query per every Person */
$criteria->with=array(
'friend1'=>array(
'joinType'=>'INNER JOIN',
),
'friend2'=>array(
'joinType'=>'INNER JOIN',
),
);
/* Tip: You can use with() and not use the joinType but by using it we are forcing a INNER JOIN that makes sense in this case */
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
/* 7) Apply sorting for the columns from the related tables */
'sort'=>array(
'attributes'=>array(
'*',
'friend1Name'=>array(
'asc'=>'friend1.name',
'desc'=>'friend1.name desc',
),
'friend2Name'=>array(
'asc'=>'friend2.name',
'desc'=>'friend2.name desc',
),
),
),
));
}
/* 8) Auto-fill friend1Name and friend2Name with the names from the related tables */
protected function afterFind () {
$this->friend1Name=$this->friend1->name;
$this->friend2Name=$this->friend2->name;
// Tip: Now you can use in your grid directly friend1Name instead of $data->friend1->name
parent::afterFind();
}