2

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

enter image description here

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

1
  • not clear what kind of relationship you have between users and user_details. I guess hasOne. So according to the manual (same link provided by ndm in his answer) the input name should be user_detail.address Commented Jul 3, 2018 at 12:09

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

4 Comments

i have follow all these above links .sorry typing mistake but i am following the naming conventions. i am updating it again.
i f i changing it to user_detail.name then validation is working but error message is not showing below each field but for user table its showing perfectlty.
@SoubhagyaKumar That's something that you need to debug further, I have no way to reproduce it, and it's a different issue than the original question. If you can't figure it out, create a new question with some short example code that reproduces the problem.
i have add a screenshot in this question .and i explained briefly about this situation there.please have a look and tell me if any solution
0

You're trying to patch your details entity with the wrong data ($this->request->getData()). But really, there is no need to create, patch and save a separate entity in your add function, because the first level of associations will be handled transparently for you. This should work just fine:

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

Or, at least, it should once you correct the field names from the details entity to include "user_detail.", as @ndm said; your HTML above is still showing $this->Form->control('address',...) instead of $this->Form->control('user_detail.address',...), though it also includes fields for city and state, which aren't in your screen shot, so it's unclear what your current version might look like.

9 Comments

i have tried with user_detail.address and user_detail.0.address but nothing is working in user table record inserted but user_details table still blank
If you debug($user); after the patchEntity call, what does it look like?
Maybe also include your initialize function from UsersTable class, so we can see the association.
'email' => '[email protected]', 'mobile' => '5136563514', 'password' => 'vhgnvhgfhfh', '[new]' => true, '[accessible]' => [ 'email' => true, 'mobile' => true, 'password' => true, 'user_status' => true, 'user_type' => true, 'created' => true, 'updated' => true, 'orders' => true, 'user_details' => true ], '[dirty]' => [ 'email' => true, 'mobile' => true, 'password' => true, 'user_detail' => true ], '[original]' => [], '[virtual]' => [], '[errors]' => [], '[invalid]' => [], '[repository]' => 'Users'
public function initialize() { parent::initialize(); $this->viewBuilder()->setLayout('admin'); $this->loadModel('Users'); $this->loadModel('UserDetails'); $this->loadComponent('Custom'); $this->loadComponent('Paginator'); }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.