我很懒,每次建完表之后都喜欢用 gii 生成 model 和 CRUD 代码,有些表简单到只需要很普通的输入,不需要对代码进行改动,很方便,如果遇到稍微特殊点的比如富文本编辑器或者日期选择之类的,可以直接找一个 widget,在表单简单修改一下就 OK 了。
但有些字段是需要在后端完成的,例如添加修改时的时间戳和操作人 ID,可能你会想到在这个 model 添加和修改的地方给对应字段加上 time()
和 Yii::$app->user->id
,但这太辛苦,只能解决当前问题,称不上偷懒,应该做的更彻底一些。
有些同学应该想到了 model 的 beforeSave()
,这可以,代码可以这么写:
use Yii;
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($insert) {
$this->created_at = time();
$this->created_by = Yii::$app->user->id;
} else {
$this->updated_at = time();
$this->updated_by = Yii::$app->user->id;
}
return true;
} else {
return false;
}
}
这应该是最简单的一个方法,但以后要是有其他需求在 beforeSave()
方法里加代码的话,代码混在一起,可能会搞得很乱,所以强烈推荐使用 behaviours()
:
use yii\behaviors\BlameableBehavior;
use yii\behaviors\TimestampBehavior;
/**
* @inheritdoc
*/
public function behaviors()
{
return [
BlameableBehavior::className(),// 不进行任何配置
[
'class' => TimestampBehavior::className(),
// 修改时填充 updated_at 字段
'attributes' => [
parent::EVENT_BEFORE_UPDATE => 'updated_at',
],
'value' => date('Y-m-d H:i:s'),// 填充的值,默认 time()
],
];
}
在以上代码添加了两个行为,第一个类 yii\behaviors\BlameableBehavior
是用来自动完成操作人 ID 字段的,第二个类 yii\behaviors\TimestampBehavior
是自动完成时间戳字段的,然后对它们进行了一些配置(如果你对配置不熟的话,不妨看看这个)。
第一个行为我没有进行任何配置,这是为了告诉大家,这两个类其实是有默认配置的,所以这些默认配置如果和自己的需求符合的话,就可以直接添加类名,你去把这两个类的内容看一遍就知道了。
需要补充的是,在执行 save()
方法的时候,会先进行验证,再触发事件,所以相关字段如果有非空之类的规则的话,save()
是无法成功的,可以考虑取消相关字段的非空规则,或者如果你已经确认接收到的数据是安全的,可以使用 save(false)
。
最后,这两个类的父类 yii\behaviors\AttributeBehavior
,如果你有更多的想法,不妨试试用这个来实现。