3
votes

So, I have this method where I save a model and its associated models. It has validation rules, but not on the fields that are causing the errors.

The data being passed to the save method is ok, the return of the save method using atomic = false is true on every field except two, that do not have any validation.

The saveAll/saveAssociated fails, and the return of $this->Model->validationErrors is the list of the fields that are not being validated as a empty array.

I already had searched for this on web and found a similar problem to mine here on StackOverflow, but the answer didn't solve my problem.

EDIT
The link to the problem similar to mine: CakePHP save failing with validation errors set but empty

EDIT 2
Here's the code. The rest of the models are ok, so I won't post it here.

**Add Method**

public function add() {
    if ($this->request->is('post')) {
        if(empty($this->request->data['User']['referer'])) {
            $this->request->data['Partner']['status'] = 1;
            $this->request->data['User']['group_id'] = 2;
            $this->request->data['User']['status'] = 1;
            $this->request->data['Customer']['birthday'] = implode("-", array_reverse(explode("/", $this->request->data['Customer']['birthday'])));
            $this->request->data['Customer']['newsletter'] = ($this->request->data['Customer']['newsletter'] == "1") ? true : false;
            $this->request->data['Customer']['accept'] = ($this->request->data['Customer']['accept'] == "1") ? true : false;

            if(!$this->request->data['Customer']['accept']) {
                $this->Session->setFlash(__('You must accept the terms and conditions to proceed.'), 'danger');
            } else {
                $this->Customer->Partner->create();
                var_dump($this->Customer->Partner->saveAssociated($this->request->data, array('atomic' => false)));
                debug($this->Customer->Partner->validationErrors);
                exit();
                if($this->Partner->saveAll($this->request->data)) {
                    $this->Session->setFlash(__('Your profile has been saved. Welcome to Abaixo da Tabela.'), 'success');
                    $this->redirect(array('controller' => 'pages', 'action' => 'display', 'home', 'admin' => false));
                } else {
                    $this->Session->setFlash('Ocorreu um erro ao tentar salvar seu perfil. Verifique se os campos estão preenchidos corretamente e tenta novamente.', 'danger');
                }
            }
        }
    }
}

** Partner Model **
class Partner extends AppModel {
    public $validate = array(
        'person_type' => array(
            'notEmpty' => array(
                'rule' => array('notEmpty'),
            ),
        ),
        'status' => array(
            'numeric' => array(
                'rule' => array('numeric'),
            ),
        ),
    );

    public $hasMany = array(
        'Address' => array(
            'className' => 'Address',
            'foreignKey' => 'partner_id',
        ),
        'Contact' => array(
            'className' => 'Contact',
            'foreignKey' => 'partner_id',
        ),
        'Customer' => array(
            'className' => 'Customer',
            'foreignKey' => 'partner_id',
        ),
        'User' => array(
            'className' => 'User',
            'foreignKey' => 'partner_id',
        ),
    );
}

** Address Model **
class Address extends AppModel {
    public $validate = array(
        'partner_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
            ),
        ),
        'address' => array(
            'notEmpty' => array(
                'rule' => array('notEmpty'),
            ),
        ),
        'number' => array(
            'notEmpty' => array(
                'rule' => array('notEmpty'),
            ),
        ),
        'zip' => array(
            'notEmpty' => array(
                'rule' => array('notEmpty'),
            ),
        ),
        'district' => array(
            'notEmpty' => array(
                'rule' => array('notEmpty'),
            ),
        ),
        'city_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
            ),
        ),
        'uf' => array(
            'notEmpty' => array(
                'rule' => array('notEmpty'),
            ),
        ),
    );

    public $belongsTo = array(
        'Partner' => array(
            'className' => 'Partner',
            'foreignKey' => 'partner_id',
        ),
        'City' => array(
            'className' => 'City',
            'foreignKey' => 'city_id',
        )
    );
}

** Customer Model **
class Customer extends AppModel {
    public $validate = array(
        'partner_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
            ),
        ),
        'birthday' => array(
            'date' => array(
                'rule' => array('date'),
            ),
        ),
    );

    public $belongsTo = array(
        'Partner' => array(
            'className' => 'Partner',
            'foreignKey' => 'partner_id',
        ),
        'City' => array(
            'className' => 'City',
            'foreignKey' => 'city_id',
        )
    );
}

** debug($this->Customer->Partner->validationErrors) **
array (size=5)
'Partner' => boolean true
'Address' => 
    array (size=7)
        'zip' => boolean true
        'address' => boolean true
        'number' => boolean true
        'adjunct' => boolean false
        'district' => boolean true
        'uf' => boolean true
        'city_id' => boolean true
'Contact' => 
    array (size=3)
        'email' => boolean true
        'phone_1' => boolean true
        'phone_2' => boolean true
'User' => 
    array (size=5)
        'username' => boolean true
        'password' => boolean true
        'password_confirm' => boolean true
        'group_id' => boolean true
        'status' => boolean true
'Customer' => 
    array (size=4)
        'genre' => boolean true
        'birthday' => boolean true
        'newsletter' => boolean false
        'accept' => boolean true

Note the two false responses in the return of the save method.

1
Would help to have a look at the code... - Nunser
use $this->Model->save($object, false); for test if this is validation error, false param mean , not validate the data. - Gonzalo Bahamondez
@Nunser There you go. @GonzaloBahamondez Disabling the validation gives me a Fatal Error: Cannot use string offset as an array on the Cake\Model\Model.php. - SandovalMatos
@ndm Yeah, I figured it out like 10min before your comment. Anyway, thank you for the response. - SandovalMatos

1 Answers

0
votes

(Answered by a question edit. Converted to a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )

The OP wrote:

Turned out that the error was in the view. The form fields for the associated models were like:

echo $this->Form->input('Customer.birthday')
echo $this->Form->input('Customer.newsletter')
echo $this->Form->input('Customer.accept')

When the correct way was:

echo $this->Form->input('Customer.0.birthday')
echo $this->Form->input('Customer.0.newsletter')
echo $this->Form->input('Customer.0.accept')

As in the Book, the fields for models with the hasMany association need a index, in that case, the 0.