cakephp 2.x how to set empty model to valid(multiple models on same page)

630 views Asked by At

I have 2 models on the same page:

  • Person (always required)

  • User (optional)

Person fields id|firstname|lastname|gender

User fields: id|username|password|password_confirm

These fields have notEmpty validation rules, password and password_confirm have a custom validation rule (matchpassword).

I want that if I don't fill any of the User fields in the view, the empty models mean valid. But if any of the fields are not empty the User validation rules are works as normally.

So save in the following cases:

  • Person all of the fields are filled and all of the User fields are empty

or

  • Person all if the fields filled and User fields are also filled

Any Other case i want to see the exact reason why i was not able to save

The main task is in the add function,but i am totally confused now, don't exactly know how to.

Update1: Sorry i make a fault the validation rule is not empty for both models

Update2:i was try to check User validation before save

    public function add() {
unset($this->Group->User->validate['username']);//i switched off the notempty rule here

if ($this->request->is('post')) {


        $this->Group->create();
        if ($this->Group->save($this->request->data))
        {
            $this->Session->setFlash(__('The group has been saved.'));

            //try to check validation before saving
            $this->Group->User->set( $this->data );
            if ($this->Group->User->validates()) {

            //group saved ok, now add people
            $group_id=$this->Group->getInsertId();
            if(!empty($this->request->data['User']))
            foreach($this->request->data['User'] as $user) {
            //loop for each person added
            $user['group_id']=$group_id;
            $this->Group->User->create();
            if($this->Group->User->save($user))
            {
            debug($this->Group->User->validates());
            $this->Session->setFlash(__('The Userhas been saved.'));}
            }//end foreach



            return $this->redirect(array('action' => 'index'));
            }else{
            $this->Session->setFlash(__('The User could not been saved.'));
            }
        } 

        else {
            $this->Session->setFlash(__('The group could not be saved. Please, try again.'));
        }


    }
}

There are following errors:The User is saved even with empty username field,even if totally empty fields saved with group_id and the rest fields are empty.

Update3: i implemented as cwbit second solution was(also modified the behavior to be compatible with 2.x),but this does not works for me

public $validate = array(

        'password'=>array('username'=>array(
        'rule'=>'notEmpty',
        'if'=>array('username')//if the username exist, the password is notEmpty if i good understand
        )

        );
2

There are 2 answers

0
drmonkeyninja On

You could check if $this->request->data['User'] is empty prior to saving/validating using Hash::filter() (see docs on Hash utility):-

if (empty(Hash::filter($this->request->data['User']))) {
    unset($this->request->data['User'])
}
1
cwbit On

First, you need to make sure to keep validation rules inside the appropriate models - i.e. Person should have no clue what goes on inside User and vice-versa. This is because for your App to be modular, scaleable, and maintain it's integrity each Model should be the ultimate authority on its own data.

option 1: Check for Data in the Controller first

That said, you can, in the Controller, choose what data should be saved - so, like @drmonkeyninja said, you could easily check to see if anything was set in $this->data['User'] and if not, remove it from the data being saved. This is probably your best bet because the Controller/View combination are exposing forms in such a way that special data combinations are possible.

option 2: Conditional Validation

If you want something a little different you can use something like a ConditionalValidation Behavior to only run certain validation rules if certain pre-conditions are met

  • only run rule XYZ if field ABC exists and == true
  • only run rule XYZ if field(s) ABC exists, is true and field DEF exists and is >= 123
  • etc.

There's a behavior for this from Cake 1.x that should be really easy to adapt for Cake 2.x (as in, just the file name needs to change)