Yii2 Gii CRUD генерация с полями пробелами в именах
У меня есть база данных PostgreSQL с пробелами в именах таблиц и полей. У меня нет контроля над этой структурой базы данных. Проблема не в именах таблиц, а в именах полей с CRUD-кодом скаффолда. Вот пример:
CREATE TABLE "public"."MILESTONES 4 FORM TABLE" (
"Estimate ID" varchar(250) NOT NULL DEFAULT 'None'::character varying COLLATE "default",
"MS 4 Name" varchar(100) NOT NULL COLLATE "default",
"MS 4 Begin" varchar(50) COLLATE "default",
"MS 4 End" varchar(50) COLLATE "default",
"MS 4 Weight" float4 DEFAULT 0.0,
"MS 4 % Oct" float4 DEFAULT 0.0,
"MS 4 % Nov" float4 DEFAULT 0.0,
....the other months here... deleted for brevity
"MS 4 % Sep" float4 DEFAULT 0.0,
"Change Control Choice" varchar(50) COLLATE "default",
"CV% MS Oct Cum" varchar(50) COLLATE "default",
"SV% MS Oct Cum" varchar(50) COLLATE "default",
"CV% MS NOV Cum" varchar(50) COLLATE "default",
"SV% MS NOV Cum" varchar(50) COLLATE "default",
....the other months here... deleted for brevity
"CV% MS Sep Cum" varchar(50) COLLATE "default",
"SV% MS Sep Cum" varchar(50) COLLATE "default"
);
Gii сгенерировал для модели следующее (мне пришлось закомментировать объявления @property, потому что PHPStorm пометил их как ошибку):
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "MILESTONES 4 FORM TABLE".
*
//* @property string $Estimate ID
//* @property string $MS 4 Name
//* @property string $MS 4 Begin
//* @property string $MS 4 End
//* @property double $MS 4 Weight
//* @property double $MS 4 % Oct
//* @property double $MS 4 % Nov
...deleted for brevity
//* @property double $MS 4 % Sep
//* @property string $Change Control Choice
//* @property string $CV% MS Oct Cum
//* @property string $SV% MS Oct Cum
...deleted for brevity...
//* @property string $CV% MS Sep Cum
//* @property string $SV% MS Sep Cum
*/
class Milestone4AR extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'MILESTONES 4 FORM TABLE';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['Estimate ID', 'MS 4 Name'], 'required'],
[['MS 4 Weight', 'MS 4 % Oct', 'MS 4 % Nov', 'MS 4 % Dec', 'MS 4 % Jan', 'MS 4 % Feb', 'MS 4 % Mar', 'MS 4 % Apr', 'MS 4 % May', 'MS 4 % Jun', 'MS 4 % Jul', 'MS 4 % Aug', 'MS 4 % Sep'], 'number'],
[['Estimate ID'], 'string', 'max' => 250],
[['MS 4 Name'], 'string', 'max' => 100],
[['MS 4 Begin', 'MS 4 End', 'Change Control Choice', 'CV% MS Oct Cum', 'SV% MS Oct Cum', 'CV% MS NOV Cum', 'SV% MS NOV Cum', 'CV% MS Dec Cum', 'SV% MS Dec Cum', 'CV% MS Jan Cum', 'SV% MS Jan Cum', 'CV% MS Feb Cum', 'SV% MS Feb Cum', 'CV% MS Mar Cum', 'SV% MS Mar Cum', 'CV% MS Apr Cum', 'SV% MS Apr Cum', 'CV% MS May Cum', 'SV% MS May Cum', 'CV% MS Jun Cum', 'SV% MS Jun Cum', 'CV% MS Jul Cum', 'SV% MS Jul Cum', 'CV% MS Aug Cum', 'SV% MS Aug Cum', 'CV% MS Sep Cum', 'SV% MS Sep Cum'], 'string', 'max' => 50],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'Estimate ID' => 'Estimate ID',
'MS 4 Name' => 'Ms 4 Name',
'MS 4 Begin' => 'Ms 4 Begin',
'MS 4 End' => 'Ms 4 End',
'MS 4 Weight' => 'Ms 4 Weight',
'MS 4 % Oct' => 'Ms 4 % Oct',
'MS 4 % Nov' => 'Ms 4 % Nov',
...deleted for brevity...
'MS 4 % Aug' => 'Ms 4 % Aug',
'MS 4 % Sep' => 'Ms 4 % Sep',
'Change Control Choice' => 'Change Control Choice',
'CV% MS Oct Cum' => 'Cv% Ms Oct Cum',
'SV% MS Oct Cum' => 'Sv% Ms Oct Cum',
...deleted for brevity...
'CV% MS Sep Cum' => 'Cv% Ms Sep Cum',
'SV% MS Sep Cum' => 'Sv% Ms Sep Cum',
];
}
}
Затем я использовал Gii для генерации кода CRUD из модели. Вы можете увидеть пример проблемы с разделом $query->andFilterWhere. Например, ... andFilterWhere(['like', 'MS 4 Name', $this->MS 4 Name]) не будет анализироваться.
Что я сделал не так, и как я могу это исправить?
Это не производственный код (пока), поэтому я могу легко скинуть то, что уже сделал, но я не могу изменить исходную структуру таблицы базы данных (мальчик, я бы хотел! Мне действительно не нравится работать над устаревшим кодом), У меня более 100 таблиц, использующих одно и то же соглашение об именах, поэтому мне нужно исправление, которое можно применить ко всем из них.
<?php
namespace app\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Milestone4AR;
/**
* Milestone4Search represents the model behind the search form about `app\models\Milestone4AR`.
*/
class Milestone4Search extends Milestone4AR
{
/**
* @inheritdoc
*/
public function rules()
{
return [
[['Estimate ID', 'MS 4 Name', 'MS 4 Begin', 'MS 4 End', 'Change Control Choice', 'CV% MS Oct Cum', 'SV% MS Oct Cum', 'CV% MS NOV Cum', 'SV% MS NOV Cum', 'CV% MS Dec Cum', 'SV% MS Dec Cum', 'CV% MS Jan Cum', 'SV% MS Jan Cum', 'CV% MS Feb Cum', 'SV% MS Feb Cum', 'CV% MS Mar Cum', 'SV% MS Mar Cum', 'CV% MS Apr Cum', 'SV% MS Apr Cum', 'CV% MS May Cum', 'SV% MS May Cum', 'CV% MS Jun Cum', 'SV% MS Jun Cum', 'CV% MS Jul Cum', 'SV% MS Jul Cum', 'CV% MS Aug Cum', 'SV% MS Aug Cum', 'CV% MS Sep Cum', 'SV% MS Sep Cum'], 'safe'],
[['MS 4 Weight', 'MS 4 % Oct', 'MS 4 % Nov', 'MS 4 % Dec', 'MS 4 % Jan', 'MS 4 % Feb', 'MS 4 % Mar', 'MS 4 % Apr', 'MS 4 % May', 'MS 4 % Jun', 'MS 4 % Jul', 'MS 4 % Aug', 'MS 4 % Sep'], '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 = Milestone4AR::find();
// 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([
'MS 4 Weight' => $this->'MS 4 Weight',
'MS 4 % Oct' => $this->'MS 4 % Oct',
'MS 4 % Nov' => $this->'MS 4 % Nov',
...deleted for brevity...
'MS 4 % Jul' => $this->'MS 4 % Jul',
'MS 4 % Aug' => $this->'MS 4 % Aug',
'MS 4 % Sep' => $this->'MS 4 % Sep',
]);
$query->andFilterWhere(['like', 'Estimate ID', $this->Estimate ID])
->andFilterWhere(['like', 'MS 4 Name', $this->MS 4 Name])
->andFilterWhere(['like', 'MS 4 Begin', $this->MS 4 Begin])
->andFilterWhere(['like', 'MS 4 End', $this->MS 4 End])
->andFilterWhere(['like', 'Change Control Choice', $this->Change Control Choice])
->andFilterWhere(['like', 'CV% MS Oct Cum', $this->CV% MS Oct Cum])
->andFilterWhere(['like', 'SV% MS Oct Cum', $this->SV% MS Oct Cum])
->andFilterWhere(['like', 'CV% MS NOV Cum', $this->CV% MS NOV Cum])
->andFilterWhere(['like', 'SV% MS NOV Cum', $this->SV% MS NOV Cum])
->andFilterWhere(['like', 'CV% MS Dec Cum', $this->CV% MS Dec Cum])
...deleted for brevity...
->andFilterWhere(['like', 'CV% MS Aug Cum', $this->CV% MS Aug Cum])
->andFilterWhere(['like', 'SV% MS Aug Cum', $this->SV% MS Aug Cum])
->andFilterWhere(['like', 'CV% MS Sep Cum', $this->CV% MS Sep Cum])
->andFilterWhere(['like', 'SV% MS Sep Cum', $this->SV% MS Sep Cum]);
return $dataProvider;
}
}
1 ответ
В вашем случае вы не можете использовать сокращенные свойства, потому что это противоречит правилам именования атрибутов PHP.
Хотя есть решения, которые вы можете использовать.
Вы можете назвать атрибут так:
$model->getAttribute('MS 4 Name')
или вы можете подготовить псевдонимы в модели, например:
public $ms4name;
А затем заполните их afterFind()
лайк:
public function afterFind()
{
$this->ms4name = $this->getAttribute('MS 4 Name');
parent::afterFind();
}
Так что с этого момента вы можете использовать
$model->ms4name