2017-08-31 135 views
0

领域的空间我有两个表名和字段名空格的PostgreSQL数据库。我无法控制这个数据库结构。问题不在于表名,而在于使用脚手架CRUD代码的字段名称。这里有一个例子:Yii2 GII 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([ '象', '4 MS名称',$这 - > MS 4名])将不会解析。

我做了什么错,我怎么能解决这个问题?

这不是生产代码(还),所以我可以很容易地吹走我已经做了,但我不能改变原始数据库表结构(男孩,我希望我能!我真的不喜欢的工作在旧版代码上)。我有超过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; 
    } 
} 

回答

0

在你的情况下,你不能使用简写属性,因为它是PHP属性命名规则的冲突。

有解决方案,您才能使用该。

可以调用属性如下:

$model->getAttribute('MS 4 Name') 

,或者你可以像模型准备别名属性:

public $ms4name; 

然后填写他们afterFind(),如:

public function afterFind() 
{ 
    $this->ms4name = $this->getAttribute('MS 4 Name'); 
    parent::afterFind(); 
} 

所以从这一点你可以使用

$model->ms4name 
+0

感谢你的帮助,bizley。我会在周末尝试这个。 – JohnG