我正在使用 Yii php 框架。我的目标很简单,我希望显示以下数据:P_id、Autor、Anio、Titulo、Resumen。我有一个名为 ScientificProduction 的模态类。
这是我的文件代码:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "scientific_production".
*
* @property int $SP_id
* @property int $User_id
* @property int $P_id
* @property string $Titulo
*/
class ScientificProduction extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'scientific_production';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['User_id', 'P_id', 'Titulo'], 'required'],
[['User_id', 'P_id'], 'integer'],
[['Titulo'], 'string', 'max' => 255],
];
}
// Define relacion con libros table
public function getLibro()
{
return $this->hasOne(Libros::class, ['Libro_id' => 'P_id']);
}
// Define relacion con cap_libros table
public function getCapLibro()
{
return $this->hasOne(CapLibros::class, ['Cap_id' => 'P_id']);
}
// Define relacion con articulos table
public function getArticulo()
{
return $this->hasOne(Articulos::class, ['Articulos_id' => 'P_id']);
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'SP_id' => 'Sp ID',
'User_id' => 'User ID',
'P_id' => 'P ID',
'Titulo' => 'Titulo',
];
}
}
现在,在我的控制器类中,我声明一个 ActiveDataProvider 来向其传递必要的查询。为此,我在我的 actionIndex 函数中声明它,以便我可以渲染我的视图文件索引。
我的actionIndex代码是这样的:
public function actionIndex()
{
$provider = new ActiveDataProvider([
'query' => ScientificProduction::find()
->select([
'scientific_production.P_id',
'COALESCE(libros.Autor, cap_libros.Autores_capitulo, articulos.Autor) AS Autor',
'COALESCE(libros.Anio, cap_libros.Anio, articulos.Anio) AS Anio',
'COALESCE(libros.Titulo, cap_libros.Titulo_capitulo, articulos.Titulo) AS Titulo',
'COALESCE(libros.Resumen, cap_libros.Resumen, articulos.Resumen) AS Resumen'
])
->leftJoin('libros', 'scientific_production.P_id = libros.Libro_id')
->leftJoin('cap_libros', 'scientific_production.P_id = cap_libros.Cap_id')
->leftJoin('articulos', 'scientific_production.P_id = articulos.Articulos_id'),
'pagination' => [
'pageSize' => 10, // Adjust page size as needed
],
'sort' => [
'attributes' => [
'P_id',
'Autor',
'Anio',
'Titulo',
'Resumen',
],
],
]);
// returns an array of Post objects
return $this->render('index', [
'dataProvider' => $provider,
]);
}
我的视图文件代码是这样的:
<?php
use yii\grid\GridView;
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' =>[
[
// you may configure additional properties here
'attribute' => 'P_id',
'headerOptions'=>[ 'style'=>'background-color:#691C32;' ]
],
[
// you may configure additional properties here
'attribute' => 'Autor',
'headerOptions'=>[ 'style'=>'background-color:#691C32' ]
],
[
// you may configure additional properties here
'attribute' => 'Anio',
'label' =>'Año',
'headerOptions'=>[ 'style'=>'background-color:#691C32' ]
],
[
// you may configure additional properties here
'attribute' => 'Titulo',
'headerOptions'=>[ 'style'=>'background-color:#691C32' ]
],
[
// you may configure additional properties here
'attribute' => 'Resumen',
'headerOptions'=>[ 'style'=>'background-color:#691C32' ]
],
],
]);
?>
我期望什么,一个包含 P_id、Autor、Anio、Titulo 和 Resumen 数据的网格表。
我能得到什么,我的 Autor、Anio 和 Resumen 列的值(未设置)。
我与其他三个表进行联接,所述表有一项寄存器。我尝试使用 yii 生成的 sql 来调试 sql 语句:
echo $dataProvider->query->createCommand()->sql;
这个命令生成了一个有效的sql语句,我在数据库中执行该语句并获得了我想要的数据。
当您像这样使用
yii\db\ActiveQuery
时:
'query' => ScientificProduction::find()
->select([
// ...
])
// ...
这就是实际发生的情况:
ScientificProduction
为查询返回的每个唯一行创建模型实例。默认情况下,
ScientificProduction
模型仅“了解”与scientific_production
数据库表中的列匹配的字段。在步骤 3 中填充模型时,只有“已知”字段会填充数据,其余字段将被忽略。
然后
yii\grid\GridView
从 yii\data\ActiveDataProvider
接收这些模型并与它们一起工作。它不直接使用 SQL 结果。这就是为什么像 P_id
和 Titulo
这样的字段很好,因为它们存在于 scientific_production
表中,但其他字段显示为空。
要修复它,您有两种选择。
1。强制
ActiveQuery
以数组形式返回结果
创建查询时,您可以告诉它您不想创建
ScientificProduction
模型的实例。通过调用 asArray()
方法,您可以强制 ActiveQuery
跳过步骤 2 和 3,并以数组形式从 DB 返回数据,因为它们来自 DB。
在创建查询时,您只需将
asArray()
方法调用添加到方法链即可。
'query' => ScientificProduction::find()
->select([
// ...
])->asArray()
// ...
2。为模型中的计算字段创建属性
如果您为模型中的计算字段准备属性,它们将在第 3 步中填充数据。例如,如下所示:
class ScientificProduction extends \yii\db\ActiveRecord
{
public $Autor;
public $Anio;
public $Resumen;
// ... rest of your model ...
}