CakePHP custom Validation rule checks unique field combination only on create

6.8k views Asked by At

I have a Database with a User model. These Users should be unique by their name and birthday. So I wrote a custom validation function called checkUnique

public function checkUnique($check){
        $condition = array(
            "User.name" => $this->data["User"]["name"],
            "User.lastname" => $this->data["User"]["lastname"],
            "User.birthday" => $this->data["User"]["birthday"]
        );

        $result = $this->find("count", array("conditions" => $condition));

        return ($result == 0);
}

The validation rule in the model:

"name" => array(
       "checkUnique" => array(
            "rule" => array("checkUnique"),
            "message" => "This User already exists.",
            "on" => "create"
       ),
)

I have two problems. The first: This validation rule also triggers on update action, implemented as

public function edit($id = null) {
        if (!$this->User->exists($id)) {
            throw new NotFoundException(__('Invalid User'));
        }
        if ($this->request->is(array('post', 'put'))) {
            if ($this->User->save($this->request->data)) {
                $this->Session->setFlash(__('Update done.'));
                return $this->redirect(array('action' => 'index'));
            } else {
                $this->Session->setFlash(__('The user can't be saved.'));
            }
        } else {
            $options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
            $this->request->data = $this->User->find('first', $options);
        }
    }

But I wrote "on" => "create", so why it triggers also on update? The second problem: If the validation rule only triggers on create, how can I manage, to trigger an validation error, if someone change the name, lastname and birthday like an other user in the Database? Then the unique validation rule should be triggered.

1

There are 1 answers

2
Guillermo Mansilla On BEST ANSWER

Remove the 'on' => 'create'. (You want to validate in both events).

Modify your custom validation rule to this

public function checkUnique() {
    $condition = array(
        "User.name" => $this->data["User"]["name"],
        "User.lastname" => $this->data["User"]["lastname"],
        "User.birthday" => $this->data["User"]["birthday"]
    );
    if (isset($this->data["User"]["id"])) {
        $condition["User.id <>"] = $this->data["User"]["id"];
        //your query will be against id different than this one when 
        //updating 
    }
    $result = $this->find("count", array("conditions" => $condition));
    return ($result == 0);
}