debuggable

 
Contact Us
 

Ensuring uniqueness in your tables

Posted on 26/3/07 by Tim Koschützki

Deprecated post

The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.

Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.

Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).

Imagine that you want to make sure that a username that is already recorded in the database is not used again. Such a feature is often used for login systems, where both email and user names are tracked down and refused, if there is already a user in the database with that name or email.

With this handy function in this can get very easy. Simply copy the source code to your AppModel class, which is found in your /cake/ folder. Then move on to the next steps to make this work.

function isUnique($field, $value, $id='') {
        $fields[$this->name.'.'.$field] = $value;
        if (empty($id))
            // add
            $fields[$this->name.'.id'] = "<> NULL";
        else
            // edit
            $fields[$this->name.'.id'] = "<> $id";
       
        $this->recursive = -1;
        if ($this->hasAny($fields))
        {
            $this->invalidate('unique_'.$field);
            return false;
        }
        else
            return true;
    }

You need to pass the form field name, its value and an optional id to it, with which you can exclude a given database row from the search. This is important to make editing work. Say for example the user with name "Peter" changes his email. If you preserve the name "Peter" in the username form field, using this function without passing it the id of Peter's row would not work. It would always reject taking on Peter's name, as there is already one "Peter" in the database.

What does your view look like?

You have to provide a tag error message for the form field with the form field's name prefixed by 'unique_':

<p>
  <label>First Name</label>
  <?php echo $html->input('Member/first_name',array('class'=>'txt'));?>
  <?php echo $html->tagErrorMsg('Member/unique_first_name','First Name is already taken!');?>
</p>

Making adding and editing rows work in the controller

Adding rows

if(!empty($this->data['Member'])) {
  if($this->Member->isUnique('first_name',$this->data['Member']['first_name'])) {
    $this->Member->save($this->data['Member']);
  }
}

Simple, isn't it?

Editing rows

Note that you have to provide the row id here as we discussed:

if(!empty($this->data['Member'])) {
  if($this->Member->isUnique('first_name',$this->data['Member']['first_name'],$this->data['Member']['id'])) {
    $this->Member->save($this->data['Member']);
  }
}

The id must be stored in a hidden field on the edit form, as you would normally do anyway to make editing work:

<p>
  <?php echo $html->hidden('Member/id');?>

  <label>First Name</label>
  <?php echo $html->input('Member/first_name',array('class'=>'txt'));?>
  <?php echo $html->tagErrorMsg('Member/unique_first_name','First Name is already taken!');?>
</p>

Happy coding! :)

 

You can skip to the end and add a comment.

postgresql said on Jun 12, 2007:

I try phpcake but in my opinion it is very low framework.

Tim Koschuetzki said on Jun 12, 2007:

very low? Why do you consider it to be low? Or do you mean slow?

if the latter I would have to agree to a certain extent...

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.