在gridview yii2中搜索/排序0到多个关系表

时间:2016-05-08 10:30:57

标签: gridview yii2

我有一张招标表,没有多少经理。我使用kartik select2小部件通过TenderAccManager模型保存它们。

这里,tender_acc_maanger表存储了招标和acc_manager表的身份。

现在我想在gridview中以逗号分隔的方式显示acc管理员名称(accManager是TenderAccManager模型中的关系名称), 到目前为止我想出了这个(在gridview小部件内):

[
    'label' => 'A/C Manager Name',
    'format' => 'raw',
    'value' => function($data) {
        $accManagers = TenderAccManager::find()
            ->where(['tender_id' => $data->id])
            ->all();

        $value = '';
        $i = 0;
        foreach($accManagers as $accManager) {
            if($i > 0) {
                $value .= ', ';
            }
            $value .= $accManager->accManager->name;
            $i++;
        }

        return $value;
    }
],

代码正在运行,但我希望搜索和排序功能也像gridview中的其他字段一样,我该怎么做?

2 个答案:

答案 0 :(得分:1)

首先,我认为您应该重新考虑在行动开始时获取此信息,并加载(这是延迟加载)。目前,您将在每一行上执行数据库查询,这是一项昂贵的操作(不需要)。

我没有想太多。我对它的第一个想法是下一个:

1)我猜你在网格视图列表中列出了所有标书,并且有一列要列出所有的Acc经理。加载它们时(我猜是在Tender Search模型搜索方法中)你应该执行两个连接(关系多对多表和Acc管理器表)。因此,当完成此步骤时,您已经全部加载,并且不必在网格视图中的每一行中对数据库执行查询。 (另外,你应该避免在视图中执行查询。)

2)嗯,你可以在你的招标模型中有公共成员AccManagers,这将是"安全"。在搜索时,在配置数据提供程序时,您可以实际配置此属性的排序。当然,您应该从查询中创建该结果的结果是逗号分隔列表,或者您希望它看起来。

当急切地加载数据并进行排序时,您已做好准备:

3)过滤数据。只是,设置搜索模型中搜索条件的部分,它实际上会比较连接的结果字符串,或者将每个AccManagers名称与插入值进行比较(它只取决于您希望过滤器如何工作)。

这些只是指导方针,我希望这对您有帮助。

祝你好运

答案 1 :(得分:0)

/ **  *这是表“招标”的模型类。

类招标扩展\ yii \ db \ ActiveRecord {

public $manager;

/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'tender';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['name', 'cost'], 'required'],
        [['cost'], 'number'],
        [['name'], 'string', 'max' => 255],
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'name' => 'Name',
        'cost' => 'Cost',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getTenderManagers()
{
    return $this->hasMany(TenderManager::className(), ['tender_id' => 'id']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getTenderManagerList()
{
    $list  = '';
    foreach ($this->tenderMaangers as $managers) {
        $list .=$managers->manager->name.' ';
    }
    return $list;
}

}

/ **  * TenderSearch代表搜索表单背后的模型frontend\models\Tender。  * /

类TenderSearch延长招标{

/**
 * @inheritdoc
 */
public function rules() {
    return [
        [['id'], 'integer'],
        [['name', 'manager'], 'safe'],
        [['cost'], 'number'],
    ];
}

/**
 * @inheritdoc
 */
public function scenarios() {
    // bypass scenarios() implementation in the parent class
    return Model::scenarios();
}

/**
 * Creates data provider instance with search query applied
 *
 * @param array $params
 *
 * @return ActiveDataProvider
 */
public function search($params) {
    $query = Tender::find();
    $query->joinWith(['tenderManagers.manager']);
    // add conditions that should always apply here

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    $dataProvider->sort->attributes['manager'] = [
        'asc' => ['manager.name' => SORT_ASC],
        'desc' => ['manager.name' => SORT_DESC],
    ];

    $this->load($params);

    if (!$this->validate()) {
        // uncomment the following line if you do not want to return any records when validation fails
        // $query->where('0=1');
        return $dataProvider;
    }

    // grid filtering conditions
    $query->andFilterWhere([
        'id' => $this->id,
        'cost' => $this->cost,
    ]);

    $query->andFilterWhere(['like', 'tender.name', $this->name]);
    $query->andFilterWhere(['like', 'manager.name', $this->manager]);

    return $dataProvider;
}

}

/ **  *这是表“tender_manager”的模型类。 * /

类TenderManager扩展\ yii \ db \ ActiveRecord {

/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'tender_maanger';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['tender_id', 'manager_id'], 'required'],
        [['tender_id', 'manager_id'], 'integer'],
        [['manager_id'], 'exist', 'skipOnError' => true, 'targetClass' => Manager::className(), 'targetAttribute' => ['manager_id' => 'id']],
        [['tender_id'], 'exist', 'skipOnError' => true, 'targetClass' => Tender::className(), 'targetAttribute' => ['tender_id' => 'id']],
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'tender_id' => 'Tender ID',
        'manager_id' => 'Manager ID',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getManager()
{
    return $this->hasOne(Manager::className(), ['id' => 'manager_id']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getTender()
{
    return $this->hasOne(Tender::className(), ['id' => 'tender_id']);
}

}

/ **  *这是表“manager”的模型类。 * /

类管理器扩展\ yii \ db \ ActiveRecord {

/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'manager';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['name'], 'required'],
        [['name'], 'string', 'max' => 255],
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'name' => 'Name',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getTenderMaangers()
{
    return $this->hasMany(TenderMaanger::className(), ['manager_id' => 'id']);
}

/ *这是招标的索引文件的网格代码。 * /

        [
            'attribute' => 'manager',
            'value' => function($model) {
               return $model->getTenderManagerList();
            },
        ],