0

My setup: Rails 3.0.9, Ruby 1.9.2

I want to generate a unique random number for a column right before creating a new record. What is the most efficient way to do this in Ruby? I understand that I can use validates_uniqueness_of but I want to ensure uniqueness beforehand.

Bob
  • 8,424
  • 17
  • 72
  • 110

3 Answers3

4

How about a before_create or before_save AR callback?

Something like:

class ModelNameHere < ActiveRecord::Base
  before_create :generate_unique_number

  private
    def generate_unique_number
      begin
        self.number = unique_number_generator()
      end while (not ModelNameHere.find_by_number(self.number).blank?)
    end

The begin..end while is basically a do-while loop taken from this answer. Haven't tested though but I think it should work.

Community
  • 1
  • 1
Rystraum
  • 1,985
  • 1
  • 20
  • 32
1

If you want to absolutely ensure uniqueness in Ruby before saving the record, then wrap it in a transaction and lock the tables. Be aware that this can cause a significant impact on your performance.

self.class.transaction do
  connection.execute('LOCK TABLES table_name WRITE')

  # do your random generation until uniqueness validation passes here

  connection.execute('UNLOCK TABLES')
end

Personally, I think I'd rather place a unique constraint on the column in the database and catch the resulting exception in case you encounter a real race condition.

Jeremy Weathers
  • 2,556
  • 1
  • 16
  • 24
  • Good suggestion on locking the table but like you said, it's heavy. Putting a unique constraint is a reasonable compromise, guess I'll throw in a unique index constraint. – Bob Jul 07 '11 at 17:53
0

maybe something like... self is new object

Object.currentkeys.each do currentkey 
    if self.key == current.key
   #The key is allready in use

    else
     #You have unique key
    end
end
user12733
  • 153
  • 1
  • 1
  • 11