我有一个Controller和一个通过giiant生成的updateAction:
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load($_POST) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
,我想通过在模型中覆盖beforeSave重命名文件:
public function beforeSave($insert) {
if ($this->isAttributeChanged('name')) {
rename($this->getOldAttribute('name') . '.pdf', $this->name . '.pdf');
}
parent::beforeSave($insert);
}
似乎已保存模型,但保存后仍呈现表单,这实际上不是。我敢肯定这是由于beforeSave
造成的,因为如果我注释掉,一切正常。使用beforeSave怎么会导致这种不正常的行为?我想念什么?非常感谢!
答案 0 :(得分:1)
如果查看beforeSave
的源代码,您会发现,如果insertion
不返回{{1},则updating
或beforeSave
进程将被取消。 }。 “似乎已保存模型”,实际上不是。
因此将您的代码调整为此:
true
答案 1 :(得分:0)
Yii和其他MVC框架具有这类功能。
虽然您可以在save()函数之前在控制器中编写“保存前”代码,但建议使用beforeSave()函数更为有用。
原因1:MVC中的M
beforeSave与模型有关,因此在模型文件中拥有一个处理模型属性(字段)的代码,而不是在控制器中拥有代码,将更为合乎逻辑。
原因2:保存用于插入和更新
在插入新记录以及更新现有记录时使用save()。在不使用beforeSave内置函数的情况下,保存代码之前,您必须具有2个“ manual”实例。 (代码行的“浪费”)
原因3:从另一个控制器保存模型
如果系统要求您扩展应用程序,现在又要面对一个需要保存相同模型的新控制器(出于某种原因-只是一种可能的情况),该怎么办-您必须复制自己的模型“保存前”代码到该控制器。如果您使用的是内置的beforeSave功能,则不会。
总而言之,框架的主要目的是减少需要编写的代码,同时保持逻辑性(MVC分离)。虽然您可以做不同的事情,但为什么不使用已有的东西呢?
一个简单的例子:
我有一个带有两个日期字段的表。每次尝试执行插入或更新操作时,都需要获取当前系统日期并根据操作类型进行操作。
public function beforeSave() {
if ($this->isNewRecord) {
$this->insertDate = new CDbExpression('NOW()');
} else {
$this->updateDate = new CDbExpression('NOW()');
}
return parent::beforeSave();
}
我曾经写过一次,所以我不必在每次对该对象调用save()时都要写。
某些数据库更喜欢不同的时间格式,因此您可以在此处进行处理:
public function beforeSave() {
$this->date = date('Y-m-d', $this->date);
return parent::beforeSave();
}