Yii2系列教程七:Behaviors And Validations
这一篇文章的开头就无需多言了,紧接着上一篇的内容和计划,这一篇我们来说说Yii2的Behavior和Validations。
Behavior
首先我们来说说Behavior,在Yii2中Behavior主要是可以用于一些常用的Model字段当中,对其进行自动化操作,比如自动添加一些时间戳字段等,这样我们就不用在每一个需要保存记录的地方分别写生成时间戳的代码了,比如前面我们在Yii2系列教程五:简单的用户权限管理中的controllers/StatusController.php
的actionCreate
方法实现的
$model->created_by = Yii::$app->user->getId();//add this line
$model->created_at = time();
$model->updated_at = time();
这些其实我们都是可以直接放在Status
这个Model的behaviors()
方法当中自动完成的。
OK,那既然这样,我们就来实现一下呗。
首先我们需要来喂我们的status表增加一个updated_by
字段,用来记录是哪个用户对一条状态进行了更新:
./yii migrate/create extend_status_table_for_updated_by
执行完上面的命令之后,来到相对应的migration
文件中,为其up()
和down()
方法增加下面的代码:
public function up()
{
$this->addColumn('{{%status}}','updated_by',Schema::TYPE_INTEGER.' NOT NULL');
$this->addForeignKey('fk_status_updated_by', '{{%status}}', 'updated_by', '{{%user}}', 'id', 'CASCADE', 'CASCADE');
}
public function down()
{
$this->dropForeignKey('fk_status_updated_by','{{%status}}');
$this->dropColumn('{{%status}}','updated_by');
}
这个时候先不急着运行./yii migrate/up
,因为这时候你运行./yii migrate/up
其实是会报错的,因为对于已创建的status来说,它updated_by
字段会默认为0,但是这个值在user
这张表中并不存在。所以我们首先需要将status
表中的几条数据删掉。鉴于这只是一个演示的小应用,为了保险起见,我将stutas
这张表删除了,并且将migration
这张表的于下面类似的两条记录删掉,以达到Yii2的migration重新创建stutas
表的目的:
m150804_035107_create_status_table
m150806_034325_extend_status_table_for_created_by
然后再执行./yii migrate/up
:
./yii migrate/up
Yii Migration Tool (based on Yii v2.0.6)
Total 3 new migrations to be applied:
m150804_035107_create_status_table
m150806_034325_extend_status_table_for_created_by
m150812_142736_extend_status_table_for_updated_by
Apply the above migrations? (yes|no) [no]:yes
*** applying m150804_035107_create_status_table
> create table {{%status}} ... done (time: 0.025s)
*** applied m150804_035107_create_status_table (time: 0.033s)
*** applying m150806_034325_extend_status_table_for_created_by
> add column created_by integer NOT NULL to table {{%status}} ... done (time: 0.036s)
> add foreign key fk_status_created_by: {{%status}} (created_by) references {{%user}} (id) ... done (time: 0.014s)
*** applied m150806_034325_extend_status_table_for_created_by (time: 0.053s)
*** applying m150812_142736_extend_status_table_for_updated_by
> add column updated_by integer NOT NULL to table {{%status}} ... done (time: 0.017s)
> add foreign key fk_status_updated_by: {{%status}} (updated_by) references {{%user}} (id) ... done (time: 0.017s)
*** applied m150812_142736_extend_status_table_for_updated_by (time: 0.037s)
数据表创建完成之后,我们需要在Status
这个Model文件中增加我们的behaviors方法:
public function behaviors()
{
return [
[
'class' => BlameableBehavior::className(),
'createdByAttribute' => 'created_by',
'updatedByAttribute' => 'updated_by',
],
'timestamp' => [
'class' => 'yii\behaviors\TimestampBehavior',
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
],
];
}
在return
的数组当中,第一个就是使用Yii2的BlameableBehavior
自动完成created_by
和updated_by
这两个字段,至于timestamp
这个数组,就是使用Yii2的TimestampBehavior
来自动完成created_at和updated_at
字段,并且这会根据数据的BEFORE_INSERT
和BEFORE_UPDATE
两种情况来自动完成添加。
需要注意的是,我们这时候需要在Status
中引入下面两个类:
use yii\behaviors\BlameableBehavior;
use yii\db\ActiveRecord;
这些工作都完成之后,我们就可以将我们原来在controllers/StatusController.php
的actionCreate
方法的相关那几行注释掉了:
public function actionCreate()
{
$model = new Status();
if ($model->load(Yii::$app->request->post())) {
/* $model->created_by = Yii::$app->user->getId();
$model->created_at = time();
$model->updated_at = time();*/
if ($model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
}
return $this->render('create', [
'model' => $model,
]);
}
注释掉之后,我们可以访问http://localhost:8999/status/create
来创建一条新的status
来看看:
点击创建按钮,你依然可以看到下面这个可爱的页面:
到这里,我们的Behavior在Yii2中就已经实现完毕了。下面来看看Validations
Validations
Yii2的Validation提供多种多样的验证机制,比如常见的email,图片,数字等,更多的验证机制和条件,你可以到这里查看文档:
http://www.yiiframework.com/doc-2.0/yii-validators-validator.html
这里我想说明的一点是,在Yii2之中,Validation通常都是通过validate()
来实现的,那么这个`validate()`` 方法的背后其实是怎么样的呢?可以看看下面这个顺序:
1. 首先检测Model当中有没有`scenarios()`方法,如果该方法存在,则首先执行该方法里面对应的场景之下的验证规则
2. 再检测Model当中的`rules()`方法,然后执行验证规则
为了演示方便,我们来创建一个新的Migrations:
./yii migrate/create create_sample_table
然后还是想之前一样,来到相对应的migration文件当中,实现up()
和down()
方法:
public function up()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
}
$this->createTable('{{%sample}}', [
'id' => Schema::TYPE_PK,
'thought' => Schema::TYPE_STRING.' NOT NULL DEFAULT ""',
'goodness' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 0',
'rank' => Schema::TYPE_INTEGER . ' NOT NULL',
'censorship' => Schema::TYPE_STRING . ' NOT NULL',
'occurred' => Schema::TYPE_DATE . ' NOT NULL',
], $tableOptions);
}
public function down()
{
$this->dropTable('{{%sample}}');
}
然后执行之:
./yii migrate/up
Yii Migration Tool (based on Yii v2.0.6)
Total 1 new migration to be applied:
m150812_153139_create_sample_table
Apply the above migration? (yes|no) [no]:yes
*** applying m150812_153139_create_sample_table
> create table {{%sample}} ... done (time: 0.026s)
*** applied m150812_153139_create_sample_table (time: 0.037s)
使用Gii生成Model文件:
再生成CRUD文件:
然后打开Sample.php
,你就可以看到Yii2为我们生成的rules()
了:
public function rules()
{
return [
[['goodness', 'rank'], 'integer'],
[['rank', 'censorship', 'occurred'], 'required'],
[['occurred'], 'safe'],
[['thought', 'censorship'], 'string', 'max' => 255]
];
}
Default Value验证
我门修改一下rules()方法里面的occurred字段的验证,给它设置一个默认值:
return [
[['goodness', 'rank'], 'integer'],
[['rank', 'censorship'], 'required'],
// Gii generate this
//[['occurred'], 'safe'],
['occurred', 'default', 'value' => date('Y-m-d')],
[['thought', 'censorship'], 'string', 'max' => 255]
];
然后当我们创建一个新的Sample的时候,如果我们将occurred
字段保留为空,那么这个字段就会默认取值为当天的日期。
Rank填入2,然后创建后是这样的:
至于另外的验证规则,你可以自己试着更改一下rules()
方法里面的规则,然后进行相应的验证。
Yii2系列教程七:Behaviors And Validations的更多相关文章
- CRL快速开发框架系列教程七(使用事务)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- ASP.NET 5系列教程(七)完结篇-解读代码
在本文中,我们将一起查看TodoController 类代码. [Route] 属性定义了Controller的URL 模板: [Route("api/[controller]") ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(七) Exception Handling Application Block 使用企业库异常处理应用程序模块的 ...
- webpack4 系列教程(七): SCSS提取和懒加载
教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步>>> (原文)webpack4 系列教程(七): SCSS 提取和懒加载. 个人技术小站: https://god ...
- (转)NGUI系列教程七(序列帧动画UITexture 和 UIsprit)
NGUI系列教程七(序列帧动画) 今天我给大家讲一下如何使用NGUI做序列帧动画.本节主要包括两方面内容,分别是使用UIspirit和使用UITexture 做序列帧动画.废话不说了,下面开始.还 ...
- 【转】PyQt5系列教程(七)控件
PyQt5系列教程(七)控件 软硬件环境 Windows 10 Python 3.4.2 PyQt 5.5.1 PyCharm 5.0.4 前言 控件是PyQt应用程序的基石.PyQt5自带很多不 ...
- Unity3D脚本中文系列教程(七)
http://dong2008hong.blog.163.com/blog/static/4696882720140311445677/?suggestedreading&wumii Unit ...
- NGUI系列教程七(序列帧动画)
今天我给大家讲一下如何使用NGUI做序列帧动画.本节主要包括两方面内容,分别是使用UIspirit和使用UITexture 做序列帧动画.废话不说了,下面开始.还要在啰嗦一句,首先大家要准备一些序列帧 ...
- Influx Sql系列教程七:delete 删除数据
前面介绍了使用insert实现新增和修改记录的使用姿势,接下来我们看一下另外一个简单的使用方式,如何删除数据 1. delete 语句 delete的官方语法如下 DELETE FROM <me ...
随机推荐
- 在shell脚本中添加暂停,按任意键继续
分析一个复杂脚本的时候,有时候需要加点暂停,分段来看,比较清晰 于是参考了一些实现,目前自己用的是这样子的 #add for debug by zqb function get_char() { SA ...
- 什么是SVC模式【转】
转自:http://blog.csdn.net/jobsss/article/details/7548550 版权声明:本文为博主原创文章,未经博主允许不得转载. ARM 处理器有二十七个寄存器,其中 ...
- 虚拟机VMware 安装CentOS6.5
对linux完全小白的情况下,也能依据下面的文章,一步一步安装使用成功! CentOS 6.5 下载http://www.linuxdown.net/CentOS/2014/0928/3371.htm ...
- 【转】spring 装配Bean中构造参数的注入
转载自:http://www.bianceng.cn/Programming/Java/201307/37027.htm spring 装配Bean中构造参数的注入 spring装配bean中还有一种 ...
- 移植WordPress到Ubuntu16.04
移植WordPress到Ubuntu16.04 新建 模板 小书匠 移植WordPress到Ubuntu16.04 搭建好LAMP环境后,可以按照以下方法,将本地站点移植到服务器上. 以WordPre ...
- 浏览器内核测试 v0.99
操作系统: Windows 7 浏览器内核: WebKit 内核(Chrome) 内核版本是: WebKit 537.36( Chrome 49.0.2593.0 S) 完整代码: Mozilla/ ...
- 关于 hibernate 中 hashCode爆栈的探讨
今天在 hibernate 的一对多映射测试 merge 方法时,出现了以下的异常: 我们可以看到,这里的错误有非常明显的重复性,很显然是做了间接递归,并且递归的调用是 hashMap 中的hashC ...
- springboot Hello World探究
Hello World探究1.POM文件1.父项目 <parent> <groupId>org.springframework.boot</groupId> ...
- Codeforces 855C - Helga Hufflepuff's Cup
855C - Helga Hufflepuff's Cup 题意 要求构建一棵树,树上至多可以存在 \(x\) 个权值为 \(k\) 的重要点,且与重要点连边的点的权值必须小于 \(k\),问有多少种 ...
- 树链剖分【CF343D】Water Tree
Description Mad scientist Mike has constructed a rooted tree, which consists of nnvertices. Each ver ...