0

What's the best way to guarantee that a code is unique? The code is XXX-XXXXX where X is a number only.

What way other than search for the code in a database table there is to make the process faster and cleaner?

Regards.

donald
  • 23,587
  • 42
  • 142
  • 223

3 Answers3

5
  1. Normal approach is to use :uniqueness validation. That handles db searching.
  2. More bulletproof is to use 1) + unique index on that field. If the saving fails without validation errors, you could generate a new code and try again.
Heikki
  • 15,329
  • 2
  • 54
  • 49
  • Could you please explain 2) ? Unique Index? – donald Jan 05 '11 at 20:50
  • http://stackoverflow.com/questions/1449459/how-to-make-column-unique-and-index-it-in-rails-migration – Heikki Jan 05 '11 at 20:53
  • Since I'm not sure what was unclear: Unique index (also unique key, http://en.wikipedia.org/wiki/Unique_key) is a database level thing that guarantees that the saved values (or combinations of them) are unique. – Heikki Jan 05 '11 at 21:00
  • But to guarantee that the saved values are unique, only :uniqueness is needed. Why the unique index? (Sorry for the questions) – donald Jan 05 '11 at 21:29
  • `:uniqueness` validation doesn't really guarantee it. It guarantees that entry was unique when the search was done. However, there's a time gap between that search and saving the new record. I have seen double entries when saving IP addresses for page views. Well.. in that case I removed the validation, used only unique index and didn't care if the saving was successful. – Heikki Jan 05 '11 at 21:36
0

Since no two times are the same, using some kind of hash based on time is the easiest way to guarantee uniqueness. If you are storing xxx-xxxx though, you are limiting yourself. You may also use a unique auto-incrementing value. Store the value server-side for the next number to be assigned and then increment it whenever you issue a new unique id.

both are acceptable options without knowing additional information

sethvargo
  • 26,739
  • 10
  • 86
  • 156
0

A hash based on time is actually not 'guarateed' to be unique. Using some type of hash is just a way to create a digest from a large source data. Since all data can then be described in 128bits (using md5) then its possible to encounter hash collisions.

The validates :uniquness will do a query to determine if the fields value has been used before. You can use this but it should not be your only solution. If the field is intended to be unique, you should place a unique index on the column in the database. If you only rely on the rails validation, you are running the risk of a race condition on data insertion into the table. I can bypass the validation, but another write could have also passed the validation and both end up getting into the table.

Are you generating the value or is it user input?

Jake Dempsey
  • 6,264
  • 1
  • 30
  • 25
  • Just to add a small comment.. What im trying to say is that there is a finite set of hashes for an infinite set of inputs... however, in many cases creating a hash is 'good enough' b/c it doesnt truly have to be unique. If I needed something truly unique, I would not use a hash. – Jake Dempsey Jan 05 '11 at 22:06
  • I'm generating it in the controller. Pelase see http://stackoverflow.com/questions/4609531/rails-3-handle-activerecordrecordnotunique-exception – donald Jan 05 '11 at 22:42