解决方案:数据库字段为可选列表时候的model和crud优化 [ 2.0 版本 ]
解决的问题:当字段值为下拉列表的时候 可以轻松设置
当我们表中有个字段应设计为enum类型时,即需要在提前预定的列表值中选定时,yii一般不建议在数据库中定义为enum,因为你或许还要在yii的model中在写一遍验证,这样一更改的话要改两处,而且还要在model中定义enum的对应显示值(也可以直接定义为中文,但是好像还不是很主流)
现在的思路:
增强下模型基类,在模型中定义一个可选值列表,这样的好处是更好的遵循mvc原则,
<?php
namespace app\components;
class ActiveRecord extends \yii\db\ActiveRecord
{
private $_range_list;
public function init()
{
parent::init();
$this->_range_list=$this->rangeList();
}
//获取rules里边的定义默认值,将这个值赋值给模型。
//框架本身是只在验证的时候才会赋值,框架的loaddeafult方法只加载数据库的默认字段值,这个方法可以在创建的时候,将默认值展示在表单中,更好的让录入人员了解
public function loadRuleDefaultValues()
{
foreach ($this->rules() as $k=>$v)
{
if($v[1]=='default' && (!isset($v['on']) || $v['on']==$this->scenario ) )
{
if(is_array($v[0]))
{
foreach($v[0] as $vv)
$this->$vv=$v['value'];
}else{
$this->$v[0]=$v['value'];
}
}
}
}
//可选值列表,将会有多组 类似 ['a'=>['a1','a2','a3'...] ]
//在子类中使用
public function rangeList()
{
return [];
}
//获取单个的可选值列表,或者一个列表里的一个值
public function getRange($attribute,$key=false)
{
$arr=$this->_range_list;
if(!isset($arr[$attribute]))
throw new \Exception('没有定义这个属性:'.$attribute.'的可选值列表');
if($key)
return $arr[$attribute][$key];
else
return $arr[$attribute];
}
}
然后在真正实现的模型中如下使用即可,举例为产品model的profit_type值:
class Pro extends \app\components\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'pro';
}
public function rangeList()
{
return [
'profit_type'=>[ 'li_run_bai_fen_bi'=>'利润的百分比(高风险)' ,'ben_jin_bai_fen_bi'=>'本金的百分比(固定收益)' ],
];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
['create_time','default','value'=>time()],
['create_ip','default','value'=>\Yii::$app->request->getUserIP()],
['create_admin', 'default', 'value'=>'11'],
[['name', 'content', 'profit', 'profit_type', 'create_time', 'create_admin', 'create_ip'], 'required'],
[['profit'], 'number','min'=>0,'max'=>1],
['profit_type' ,'in' ,'range'=>array_keys( $this->getRange('profit_type'))],
[['create_time', 'create_admin'], 'integer'],
[['name'], 'string', 'max' => 30],
[['content'], 'string', 'max' => 255],
[['profit_type', 'create_ip'], 'string', 'max' => 25],
];
}
下面是视图使用
from中
<?= $form->field($model, 'profit_type')->dropDownList($model->getRange('profit_type'),['prompt'=>'请选择']) ?>
detailView中本字段值
'profit_type'=> [ // the owner name of the model
'label' => 'profit_type',
'value' => $model->getRange('profit_type',$model->profit_type),
],
grid中的字段值:
'profit_type'=>[
'attribute' => 'profit_type',
'value'=>function ($model, $key, $index, $column){
return $model->getRange('profit_type',$model->profit_type);
},
'filter'=> $searchModel->getRange('profit_type'),
],
以上是个人经验,不知道大家怎么看
wow6haka 济南
注册时间:2012-05-17
最后登录:2020-05-11
在线时长:40小时39分
最后登录:2020-05-11
在线时长:40小时39分
- 粉丝8
- 金钱235
- 威望20
- 积分835
共 1 条评论
楼主一看就是做金融o2o的
。。。。。。