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.
Update: I’ve corrected some of my misconceptions about using multiple scopes with one validates uniqueness of. Read the article.