Yii2单个表单更新两个数据库表数据失败的问题求助
表单数据更新失败问题排查与修复
问题概述
我创建了一个表单,尝试通过处理类和控制器实现数据更新,但提交修改后数据库中的数据并未更新,表单也仍显示原有数据。
数据库结构
person: Code: Pets: id| PersonId | name | power Id | PesonId Id | Kind | PersonId | type 1 | 111 | Lufy | Elastic 1 | 111 1 | Dog | 190 | Dog 5 | 190 | Ace | Fire 2 | 190 2 | Cat | 190 | Cat
现有代码
表单模型(Form.php)
class Form extends Model { /** * @var string */ public $name; /** * @var string */ public $power; /** * @var string */ public $kind; public function rules() { return [['name','power','kind']]; } public function attributeLabels() { return [ 'name' => 'Name', 'power' => 'Power', 'kind' => 'Kind' ]; } }
视图代码
use models\Form; /** * @var $form Form */ <?php $form = ActiveForm::begin(['type' => ActiveForm::TYPE_HORIZONTAL]); ?> <?= $form->field($form, 'name'); ?> <?= $form->field($form, 'power'); ?> <?= $form->field($form, 'kind'); ?> <?= Html::sterSubmitButton('Save'); ?> <?php ActiveForm::end();
控制器代码(FormController.php)
class FormController extends Controller { /** * @return string */ public function actionIndex() { $form = new Form(); if (Yii::$app->request->isPost && $form->load(Yii::$app->request->post())) { $formClass = new FormClass($form); $webshop->processForm($webshopForm); } $formClass = new FormClass($form); return $this->render('index', [ 'form' => $formClass->getForm(), ]); } }
处理类代码(FormClass.php)
class ClassForm { /** * @var Person */ public $person; /** * @var Form */ private $form; public functionn __construct(Form $form) { $this->form = $form; // 已登录为特定用户 $this->person = Yii::$app->user->identity->personData; } public function getForm() { $kind = $this->person->getPetSetting(Pets::TYPE_KIND)->one(); $this->form->name = $this->person->name; $this->form->power = $this->person->power; $this->form->name = $kind = $kind ? $kind->kind : null; return $this->form; } public function processForm(Form $form) { $form->save(); } }
关联模型代码
class Code extends ActiveRecord implements IdentityInterface { public function getPersonData() { return $this->hasOne(Person::class, ['PersonId'=>'PersonID']); } } class Person extends ActiveRecord implements IdentityInterface { public function getPetSetting($type) { return $this->hasOne(Pet::class, ['PersonId'=>'PersonID'])->andWhere(['type'=>$type]); } }
问题排查与修复步骤
1. 变量名与类名错误
- 控制器中误用未定义的
$webshop和$webshopForm,应改为$formClass->processForm($form); - 处理类类名需与控制器实例化的
FormClass一致,原类名ClassForm改为FormClass - 处理类构造函数拼写错误:
public functionn __construct→public function __construct
2. 表单赋值错误
getForm方法中错误覆盖name字段值,应将宠物类型赋值给表单kind属性:
// 原代码 $this->form->name = $kind = $kind ? $kind->kind : null; // 修复后 $this->form->kind = $kind ? $kind->kind : null;
3. 表单验证规则错误
Form模型的rules方法返回格式不符合Yii要求,需补充验证规则,比如必填校验:
public function rules() { return [ [['name', 'power', 'kind'], 'required'], ]; }
4. 提交按钮拼写错误
视图中Html::sterSubmitButton → Html::submitButton
5. 处理类未实际更新数据库
Form是普通Model,无内置save()方法,需在processForm中手动更新数据库记录:
public function processForm(Form $form) { if (!$form->validate()) { return; } // 更新Person表 $this->person->name = $form->name; $this->person->power = $form->power; $this->person->save(false); // 更新Pets表 $pet = $this->person->getPetSetting(Pets::TYPE_KIND)->one(); if ($pet) { $pet->Kind = $form->kind; $pet->save(false); } else { $pet = new Pets(); $pet->PersonId = $this->person->PersonId; $pet->Kind = $form->kind; $pet->type = Pets::TYPE_KIND; $pet->save(false); } }
6. 字段大小写一致性问题
关联模型中关联条件字段名保持统一,比如Person模型的getPetSetting方法:
return $this->hasOne(Pet::class, ['PersonId' => 'PersonId'])->andWhere(['type' => $type]);
7. 提交后刷新数据
控制器处理完提交后,重新实例化处理类以加载最新数据库数据:
if (Yii::$app->request->isPost && $form->load(Yii::$app->request->post())) { $formClass = new FormClass($form); $formClass->processForm($form); // 重新实例化加载最新数据 $formClass = new FormClass($form); }
修复后控制器代码示例
class FormController extends Controller { public function actionIndex() { $form = new Form(); if (Yii::$app->request->isPost && $form->load(Yii::$app->request->post())) { $formClass = new FormClass($form); $formClass->processForm($form); $formClass = new FormClass($form); } else { $formClass = new FormClass($form); } return $this->render('index', [ 'form' => $formClass->getForm(), ]); } }
内容的提问来源于stack exchange,提问作者TLausie
相关产品推荐
相关产品推荐

