Reputation: 710
in my Rails 4 app i would like to override Active Record to create records with ids that have 7 digits of random numbers. Such as 4526378 instead of 1. I found a way to do this but im not sure its the right way to go about doing this. In my models i have:
class App < ActiveRecord::Base
after_initialize :add_id
def add_id
self.id ||= SecureRandom.random_number(9999999) if self.new_record?
end
end
Is this an acceptable way to do this? Will there be any collisions and if so what would happen, would it try again to create a record with a new SecureRandom. Also is there any way i can setup and initializer.rb file in my config/initializers that automatically does this for every model? Thanks
Ok so I added an initializer called active_record.rb in my config/initializers directory. The code inside looks like:
class ActiveRecord::Base
before_create :set_id
def set_id
self.id = SecureRandom.random_number(9999999)
end
end
This code above actually works perfectly but now a collision is the issue. In this code can i perform a check to make sure its unique? If its not then generate a new one. I would also be into changing it to SecureRandom.hex
in order to allow letters so a chance of a collision descreases.
Upvotes: 2
Views: 545
Reputation: 239270
I would probably leave id
alone, and add another field to hold the random ID. Then, before create, generate new random IDs until you hit a unique one.
class ActiveRecord::Base
validates :random_id, uniqueness: true
before_create :set_random_id
def set_random_id
loop do
self.random_id = SecureRandom.random_number(9999999)
break unless find_by_random_id(self.random_id)
end
end
end
Note that, the more records you have, the longer it will take to find a random ID that isn't taken. This is why you should probably use a larger random number than 9999999, like a UUID where collisions are virtually impossible.
Upvotes: 5