1
votes

When I save the information from a registration form I have some validation rules on the username and email fields (I've pasted the rules below). Validation is called automatically with the saveAll() function.

The problem is that the isUnique rule on the username field doesn't work at all (doesn't return any error). The other rules for this field work just fine, and the unique validation for the email field also works. I can't seem to figure out why this is happening, when the two rules are basically the same.

var $validate = array(

    'username' => array(

        'isUnique' => array (

            'rule' => 'isUnique',

            'message' => 'This username already exists.'),

        'custom' => array (

            'rule' => array('custom', '/^[A-Za-z0-9,\.-_]*$/i'), 

            'message' => 'The username can only contain letters, numbers, _, - and .'),

        'minLength' => array(

            'rule' => VALID_NOT_EMPTY,

            'message' => 'You must fill in the username.')          
    ),

    'email' => array(

        'isUnique' => array (

            'rule' => 'isUnique',

            'message' => 'This email address already exists in our database.'),

        'valid' => array (

            'rule' => array('email', false),

            'message' => 'Invalid email.'),

        'minLength' => array(

            'rule' => VALID_NOT_EMPTY,

             'message' => 'You must fill in the email address.')

    )

);
5
I'm pretty certain that in order for it to know it's unique, you need to set a primary key in your model file, and also pass that same field to be saved in your post data.David Yell
I've already declared the username field as primary key in the model and it is the same field from the post data, also, I've checked and the contents of the field is correct. I'm not sure it has to be a primary key, however. The unique rule works just file for the email, even though it's not a primary key.A. M.
Try to add 'allowEmpty' => false, or 'required' => true, after 'rule' => 'isUnique',.bancer
Thank you, but that doesn't seem to work, unfortunately.A. M.

5 Answers

6
votes

The "isUnique" rule looks for repeating values in other rows. Which will create a problem if the "isUnique" test is also the primary key. So, based on your rules/model above, if you look at the SQL dump when the rule is run, you will likely see something like

SELECT COUNT(*) FROM users WHERE username = 'x' AND username != 'x'

This obviously returns 0 or "unique" in the test. Fix would be to set the primary key equal to something other than the field you are testing the rule on. When you do that, the SQL dump should show something like

SELECT COUNT(*) FROM users WHERE username = 'x' AND key != 'y'

This will return the >0 when the field is not unique and the desired functionality will be restored.

3
votes

I still can't find what the problem is, so as a temporary solution I've written a custom rule. In case somebody else needs this:

var $validate = array(
    'username' => array(
        'isUnique' => array (
            'rule' => array('checkUniqueUser'),
            'message' => 'This username already exists.'
        )
    )
)

function checkUniqueUser() {
    return ($this->find('count', array('conditions' => array('User.username' => $this->data['User']['username']))) == 0);
}
1
votes

Here is how to use isUnique valdiation rule in cakephp 2.3. let say you have a field 'username' wants to be unique, the following code will do the trick.

'username' => array(
'notempty' => array(
'rule' => array('notempty'),
'update' operations
),
'rule' => 'isUnique',
'message' => 'User alread exists!'
),
0
votes

Looked at my user model, and it looks like this:

var $validate = array(
    'username' => array(
        'inUse' => array (
            'rule' => array('isUnique', 'username')
        )
    )
)
-1
votes

Place $this->Form->hidden('id') in your form. It should work.