我需要能够根据相关的外部属性从GridView进行搜索。
我有两个关系表:
operators (id, name, country)
platforms (id, operator_id, platform)
许多平台都属于一个运营商。
到目前为止我所管理的是当我搜索平台(名称)时,列出具有该平台的运算符,但仍然在GridView中我获得该运算符的所有平台。我只需要匹配的那些显示:
Search for "windows" in Platforms
Name Country Platforms
=======================================
Oper1 Egypt linux1, windows3, windows4
Oper5 Germany Mac, windows2, Mac-b
我希望平台中根本不会列出不匹配的那些。
这是来自运营商模型的getPlatforms:
public function getPlatforms()
{
return $this->hasMany(Platforms::className(), ['operator_id' => 'id']);
}
我想我需要在此处限制结果,但如何在此处访问平台搜索文本?
视图中的GridView:
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'tableOptions'=>['class'=>'table table-condensed'],
'columns' => [
#['class' => 'yii\grid\SerialColumn'],
#'id',
'abbr',
'name',
'country',
[
'attribute' => 'platforms',
'format' => 'raw',
'value' => function ($model) {
// RETURN A COMMA LIST OF THE PLATFORMS
return $this->render('_platformsInline', [
'model' => $model->platforms,
]);
}
],
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
OperatorsSearch的搜索功能:
public function search($params)
{
$query = Operators::find();
$query->joinWith(['platforms']);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$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,
// 'platforms.platform' => $this->platforms,
]);
$query->andFilterWhere(['like', 'abbr', $this->abbr])
->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'country', $this->country])
->andFilterWhere(['like', 'platforms.platform', $this->platforms]);
// var_dump($query->createCommand()->rawSql);
// exit;
return $dataProvider;
}
修改
所以这里有更深入了解后台发生的事情(在我尝试解决这个问题的时候在这里倾注我的笔记)。
当我使用当前代码渲染()时,这些是(最重要的)查询在数据库中发生:
35 Query SELECT COUNT(*) FROM `operators` LEFT JOIN `platforms` ON `operators`.`id` = `platforms`.`operator_id` WHERE `platforms`.`platform` LIKE '%windows%'
This one returns:
+----------+
| COUNT(*) |
+----------+
| 4 |
+----------+
35 Query SELECT `operators`.* FROM `operators` LEFT JOIN `platforms` ON `operators`.`id` = `platforms`.`operator_id` WHERE `platforms`.`platform` LIKE '%windows%' ORDER BY `abbr` LIMIT 20
(Note the duplicate returned results)
+----+-------+-----------------+---------+
| id | abbr | name | country |
+----+-------+-----------------+---------+
| 39 | HP-KW | Hewlett Packard | Kuwait |
| 43 | DL-DZ | Dell | Algeria |
| 43 | DL-DZ | Dell | Algeria |
| 43 | DL-DZ | Dell | Algeria |
+----+-------+-----------------+---------+
35 Query SELECT * FROM `platforms` WHERE `operator_id` IN (39, 43)
(And here we take all the platforms based on the match above)
+-----+-------------+---------------------------+-------------+
| id | operator_id | platform | plat_status |
+-----+-------------+---------------------------+-------------+
| 50 | 39 | Linux2 | 1 |
| 65 | 39 | Mac1 | 1 |
| 85 | 39 | Mac2 | 0 |
| 102 | 39 | Windows1 | 0 |
| 124 | 39 | Linux3 | 0 |
| 33 | 43 | Linux with gadgets | 0 |
| 62 | 43 | Virtual windows plat | 0 |
| 77 | 43 | Mac1 | 0 |
| 90 | 43 | Mac2 | 0 |
| 91 | 43 | MM | 0 |
| 110 | 43 | MM2 | 0 |
| 126 | 43 | Windows on VM | 0 |
| 127 | 43 | Windows2 on VM | 0 |
+-----+-------------+---------------------------+-------------+
我认为我现在正处于一个完全错误的角度。
答案 0 :(得分:0)
如何使用:
return $this->render('_platformsInline', [
'model' => $model->getPlatforms()->andWhere('like','platform', $searchModel->platforms)->all(),
]);
通过这种方式,您使用关联的getPlatforms()方法访问ActiveQuery,添加where子句以仅获取满足OperatorsSearch-&gt;平台给出的条件的子句。
答案 1 :(得分:0)
到目前为止我所理解的是您能够正确搜索,但您希望隐藏那些当前未搜索的平台,即使操作员已将该平台分配给他。
Default Operators Lists
Name Country Platforms
=======================================
Oper1 Egypt linux1, windows3, windows4
Oper5 Germany Mac, windows2, Mac-b
在平台过滤器输入中搜索"windows"
,输出应如下所示
Name Country Platforms
=======================================
Oper1 Egypt windows3, windows4
Oper5 Germany windows2,
也许有其他方法可以做到这一点,但其中一种方法是查找$_GET
即Yii::$app->request->get()
,因为它具有您搜索的值,您可以用来进行比较。
我假设您在platforms
模型中定义了名为OperatorsSearch
的自定义属性,并将其添加到safe
规则中。
我不确定为什么你需要一个视图来呈现逗号分隔值,但由于它没有被添加,我会发布没有视图的解决方案你可以根据需要调整它,将列配置更改为以下
[
'attribute' => 'platforms' ,
'format' => 'raw' ,
'value' => function ($model) {
$html='';
foreach ( $model->platforms as $platform ) {
if ( isset ( Yii::$app->request->get ( 'OperatorsSearch' )['my_platforms'] ) && Yii::$app->request->get ( 'OperatorsSearch' )['my_platforms'] !== '' ) {
$html .= (strpos ( $platform->platform , Yii::$app->request->get ( 'OperatorsSearch' )['my_platforms'] ) === FALSE) ? '' : $platform->platform . ',';
} else {
$html .= $platform->platform . ',';
}
}
return $html;
}
] ,