Rails and the MySQL Unique Index with validates_uniqueness_of

So I just found this feature of rails’ activerecord pattern when I was adding some unique indeces to my mysql tables. Basically, whenever you have a unique index, you also want to add some client side code to say, “hey, you can’t do that,” instead of barfing out an error message to the user.
This is handled with validates_uniqueness_of in rails.

Say we have a table, widgets that has two columns: id and name. Id is of course, our primary key, but say we want to ensure that name is unique at the database level, and we make name a unique key. Now, we must do some checking to ensure that the code never tries to insert a non unique name.

In rails, in your widget model, you’d simply add: validates_uniqueness_of :name.

This magic sauce makes rails check before inserting or updating. If you don’t want to have the overhead of an index, you could use this w/o an index, and it would still work.

validates_uniqueness_of provides lots of other magic, most notably the ability to specify a scope for your uniqueness. This is the true power of the feature, letting you do some really complicated things.

Say we had the same table, but all widgets come in multiple sizes, so we have id, name, and size. We can have a widget named Fizzlecutter 3000, but it can come in Small, Medium, or Large. We want to ensure that Fizzlecutter 3000 can be inserted multiple times, but only with different sizes. We do this by saying:

validates_uniqueness_of :name, :scope => size

You can have multiple uniqueness validators, to create compliated business rule sets.

Cool!

Update: I’ve corrected some of my misconceptions about using multiple scopes with one validates uniqueness of.  Read the article.

Published by

matt

I'm a software engineer in New Orleans interested in making things, growing things, big fast computers, media convergence, and pugs.

-24 thoughts on “Rails and the MySQL Unique Index with validates_uniqueness_of”

  1. hello
    I have a table with id, name and surname.id is the primary index and i have an unique index named nom on (name,surname). I would like that the name&surname will be unique in a row in the table. In the model:
    validates_uniqueness_of :name, :surname ???????
    I hope you see what I mean.
    Thank you for answer

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>