cakephp 模型验证错误消息未显示在 hasOne 关联中

2022-01-02 00:00:00 model php cakephp-3.0

我想在单个表单中使用 association 进行 model 验证.我有两个表 users(父表)和 user_details(子表).现在模型验证仅适用于用户表.我也希望它用于 userDetails 表.它们之间的关系是hasOne.

验证只对用户表有效,因为我只为用户表创建了 newEntity.

usersController.php(控制器代码)

 公共函数 add() {$user = $this->Users->newEntity();$userDetail = $this->UserDetails->newEntity();如果 ($this->request->is('post')) {$user = $this->Users->patchEntity($user, $this->request->getData());if ($this->Users->save($user)) {$userDetail = $this->UserDetails->patchEntity($userDetail, $this->request->getData());$userDetail->user_id = $user->id;if ($this->UserDetails->save($userDetail)) {$this->Flash->success(__('用户已保存.'));} 别的 {$this->Flash->error(__('用户无法保存.请再试一次.'));}$this->redirect($this->referer());} 别的 {$this->Flash->error(__('用户无法保存.请再试一次.'));}}$this->set(compact('user','userDetail'));}

UsersTable.php(父模型)

 public function validationDefault(Validator $validator) {$验证器-> 整数('id')->allowEmpty('id', 'create');$验证器-> 电子邮件('电子邮件')->requirePresence('email', 'create')->notEmpty('email');$验证器->标量('移动')-> maxLength('mobile', 10,'最大长度应为 10 位数字')->minLength('mobile', 10,'最小长度应为 10 位数字')->requirePresence('移动', '创建')->notEmpty('移动');$验证器->标量('密码')->maxLength('password', 20,'最小长度应为 20 位数字')->minLength('password', 4,'最小长度应为 4 位数字')->requirePresence('密码', '创建')->notEmpty('密码');返回 $validator;}

UserDetailsTable.php(子模型)

 公共函数validationDefault(Validator $validator){$验证器-> 整数('id')->allowEmpty('id', 'create');$验证器->标量('名称')-> maxLength('姓名', 50)->requirePresence('name', 'create')->notEmpty('name');$验证器->标量('pin')-> maxLength('pin', 6)->requirePresence('pin', 'create')->notEmpty('pin');$验证器->标量('地址')-> maxLength('地址', 4294967295)->requirePresence('地址', '创建')->notEmpty('地址');返回 $validator;}

add.ctp

Form->create($user, ['url' => ['controller' => 'Users', 'action' => 'add'], 'class' => 'form-horizo​​ntal', 'id' => 'add-user']);?><div class="box-body"><div class="form-group"><label for="name" class="col-sm-2 control-label">Name <label class="text-danger">*</label></label><div class="col-sm-3"><?= $this->Form->control('user_detail.name', ['class' => 'form-control', 'id' => 'name', 'placeholder' =>'名称', '类型' => '文本', '标签' => 假]);?>

<label for="email" class="col-sm-2 control-label">Email <label class="text-danger">*</label></label><div class="col-sm-3"><?= $this->Form->control('email', ['class' => 'form-control', 'id' => 'email', 'placeholder' => 'Email', 'type' => 'email', 'label' => false]);?>

<div class="form-group"><label for="mobile" class="col-sm-2 control-label">Mobile

<label for="password" class="col-sm-2 control-label">Password <label class="text-danger">*</label></label><div class="col-sm-3"><?= $this->Form->control('password', ['class' => 'form-control', 'id' => 'password', 'placeholder' => 'Password', 'type' => 'text', 'label' => false]);?>

<div class="col-sm-2"><button type="button" class="btn btn-default"><i class="fa fa-refresh"></i>生成

<div class="form-group"><label for="state" class="col-sm-2 control-label">State</label><div class="col-sm-3"><?= $this->Form->select('user_detail.state', ['Odisha', 'Hyderbad'], ['class' => 'form-control', 'id' =>'状态', '标签' => 假]);?>

<label for="city" class="col-sm-2 control-label">City</label><div class="col-sm-3"><?= $this->Form->select('user_detail.city', ['Bhubaneswar', 'Cuttack'], ['class' => 'form-control', 'id' =>'city', 'label' => false]);?>

<div class="form-group"><label for="inputEmail3" class="col-sm-2 control-label">地址</label><div class="col-sm-3"><?= $this->Form->control('user_detail.address', ['class' => 'form-control', 'id' => 'address', 'type' =>'textarea', 'rows' => 2, 'label' => false]);?>

<label for="pin" class="col-sm-2 control-label">Pin</label><div class="col-sm-3"><?= $this->Form->control('user_detail.pin', ['class' => 'form-control', 'id' => 'pin', 'placeholder' =>'Pin', 'type' => 'text', 'label' => false]);?>

<div class="form-group"><div class="col-sm-offset-2 col-sm-10"><button type="button" class="btn btn-default">取消</button><?= $this->Form->control('Save', ['class' => 'btn btn-primary', 'id' => 'submit', 'type' => 'submit', 'label' => false, 'div' => false, 'templates' => ['submitContainer' => '{{content}}']]);?>

<?= $this->Form->end();?>

这是参考图片

在这张图片中,所有字段都是必填的所有字段都来自用户表...只有地址字段来自 user_details 表.现在您可以看到显示名字字段的错误消息,但未显示地址字段的错误消息.地址字段验证工作,但不知道为什么错误消息未显示.

users 表中的名字和 user_details 表中的地址

提前致谢

解决方案

验证只对用户表有效,因为我只为用户表创建了 newEntity.

与此无关.问题是您没有正确遵循命名约定.

文件名必须匹配类名,所以它是UserDetailsTable.php,而不是UserDetails.phpUsersTable.php,而不是usersTable.php

hasOne 关联的正确属性名称是关联名称的单数、带下划线的变体,因此对于 UserDetails 来说应该是 user_detail,因此相关表单控件的名称应为user_detail.name.

另见

  • 食谱>CakePHP 概览 > CakePHP 约定 > 文件和类名约定
  • Cookbook > Views > Helpers > Form > 为关联数据创建输入
  • 食谱 > 数据库访问&ORM > 保存数据 > 保存 HasOne 关联
  • 食谱> 数据库访问 &ORM > 关联 - 将表链接在一起 > HasOne 关联

i want to do model validation with association in a single form. i have two tables users(parent table) and user_details(child table).now model validation is working for users table only.i want it for userDetails table also. relation between them is hasOne.

validation working for only users table because i have created newEntity for users table only.

usersController.php (controller code)

 public function add() {
        $user = $this->Users->newEntity();
        $userDetail = $this->UserDetails->newEntity();
        if ($this->request->is('post')) {
            $user = $this->Users->patchEntity($user, $this->request->getData());
            if ($this->Users->save($user)) {
                $userDetail = $this->UserDetails->patchEntity($userDetail, $this->request->getData());
                $userDetail->user_id = $user->id;
                if ($this->UserDetails->save($userDetail)) {
                    $this->Flash->success(__('The user has been saved.'));
                } else {
                    $this->Flash->error(__('The user could not be saved. Please, try again.'));
                }
                $this->redirect($this->referer());
            } else {
                $this->Flash->error(__('The user could not be saved. Please, try again.'));
            }
        }
        $this->set(compact('user','userDetail'));
    }

UsersTable.php (parent model)

 public function validationDefault(Validator $validator) {
        $validator
                ->integer('id')
                ->allowEmpty('id', 'create');

        $validator
                ->email('email')
                ->requirePresence('email', 'create')
                ->notEmpty('email');


        $validator
                ->scalar('mobile')
                ->maxLength('mobile', 10,'Maximum length should be 10 digits')
                ->minLength('mobile', 10,'Minimum length should be 10 digits')
                ->requirePresence('mobile', 'create')
                ->notEmpty('mobile');

        $validator
                ->scalar('password')
                ->maxLength('password', 20,'Minimum length should be 20 digits')
                ->minLength('password', 4,'Minimum length should be 4 digits')
                ->requirePresence('password', 'create')
                ->notEmpty('password');


        return $validator;
    }

UserDetailsTable.php (child model)

 public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->scalar('name')
            ->maxLength('name', 50)
            ->requirePresence('name', 'create')
            ->notEmpty('name');

        $validator
            ->scalar('pin')
            ->maxLength('pin', 6)
            ->requirePresence('pin', 'create')
            ->notEmpty('pin');

        $validator
            ->scalar('address')
            ->maxLength('address', 4294967295)
            ->requirePresence('address', 'create')
            ->notEmpty('address');

        return $validator;
    }

add.ctp

<?= $this->Form->create($user, ['url' => ['controller' => 'Users', 'action' => 'add'], 'class' => 'form-horizontal', 'id' => 'add-user']); ?>

        <div class="box-body">
            <div class="form-group">
                <label for="name" class="col-sm-2 control-label">Name <label class="text-danger">*</label></label>
                <div class="col-sm-3">
                    <?= $this->Form->control('user_detail.name', ['class' => 'form-control', 'id' => 'name', 'placeholder' => 'Name', 'type' => 'text', 'label' => false]); ?>
                </div>
                <label for="email" class="col-sm-2 control-label">Email <label class="text-danger">*</label></label>
                <div class="col-sm-3">
                    <?= $this->Form->control('email', ['class' => 'form-control', 'id' => 'email', 'placeholder' => 'Email', 'type' => 'email', 'label' => false]); ?>
                </div>
            </div>
            <div class="form-group">
                <label for="mobile" class="col-sm-2 control-label">Mobile <label class="text-danger">*</label></label>
                <div class="col-sm-3">
                    <?= $this->Form->control('mobile', ['class' => 'form-control', 'id' => 'mobile', 'placeholder' => 'Mobile', 'type' => 'text', 'label' => false]); ?>
                </div>
                <label for="password" class="col-sm-2 control-label ">Password <label class="text-danger">*</label></label>
                <div class="col-sm-3">
                    <?= $this->Form->control('password', ['class' => 'form-control', 'id' => 'password', 'placeholder' => 'Password', 'type' => 'text', 'label' => false]); ?>
                </div>
                <div class="col-sm-2">
                    <button type="button" class="btn btn-default"><i class="fa fa-refresh"></i> Generate</button>
                </div>
            </div>
            <div class="form-group">
                <label for="state" class="col-sm-2 control-label">State</label>
                <div class="col-sm-3">
                    <?= $this->Form->select('user_detail.state', ['Odisha', 'Hyderbad'], ['class' => 'form-control', 'id' => 'state', 'label' => false]); ?>

                </div>
                <label for="city" class="col-sm-2 control-label">City</label>
                <div class="col-sm-3">
                    <?= $this->Form->select('user_detail.city', ['Bhubaneswar', 'Cuttack'], ['class' => 'form-control', 'id' => 'city', 'label' => false]); ?>
                </div>
            </div>
            <div class="form-group">
                <label for="inputEmail3" class="col-sm-2 control-label">Address</label>
                <div class="col-sm-3">
                    <?= $this->Form->control('user_detail.address', ['class' => 'form-control', 'id' => 'address', 'type' => 'textarea', 'rows' => 2, 'label' => false]); ?>
                </div>
                <label for="pin" class="col-sm-2 control-label">Pin</label>
                <div class="col-sm-3">
                    <?= $this->Form->control('user_detail.pin', ['class' => 'form-control', 'id' => 'pin', 'placeholder' => 'Pin', 'type' => 'text', 'label' => false]); ?>
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="button" class="btn btn-default">Cancel</button>
                    <?= $this->Form->control('Save', ['class' => 'btn btn-primary', 'id' => 'submit', 'type' => 'submit', 'label' => false, 'div' => false, 'templates' => ['submitContainer' => '{{content}}']]); ?>

                </div>
            </div>
        </div>

        <?= $this->Form->end(); ?>

here is the image for reference

in this image all fields are mandatory all fields are from users table...only address field is from user_details table.now you can see error message showing for first name field but error message not showing for address field.validation working for address field but don't know why error message is not displaying.

first name from users table and address from user_details table

thanks in advance

解决方案

validation working for only users table because i have created newEntity for users table only.

That has nothing to do with it. The problem is that you are not following the naming conventions properly.

Filenames must match classnames, so it's UserDetailsTable.php, not UserDetails.php, UsersTable.php, not usersTable.php, etc.

And the correct property name for a hasOne association, is the singular, underscored variant of the association name, so for UserDetails that would be user_detail, consequently the name for the related form control should be user_detail.name.

See also

  • Cookbook > CakePHP at a Glance > CakePHP Conventions > File and Class Name Conventions
  • Cookbook > Views > Helpers > Form > Creating Inputs for Associated Data
  • Cookbook > Database Access & ORM > Saving Data > Saving HasOne Associations
  • Cookbook > Database Access & ORM > Associations - Linking Tables Together > HasOne Associations

相关文章