18

I have a requirement to be able to identify a record in a table, in this case a user table, by a unique key which does not give away the ordering of the records in the table.

Currently I have primary key field and the routes that are generated look like:

/users/1

However, I'd like to be able to generate a route like:

/users/kfjslncdk

I can wire everything up on the route side, database side etc.. but I'm not sure what the best way to generate a unique string identifier would be in rails. I'd like do something like:

before_save :create_unique_identifier

def create_unique_identifier
    self.unique_identifier = ... magic goes here ...
end

I was thinking I could use the first part of a guid created using UUIDTools, but I'd need to check to make sure it was unique before saving the user.

Any advice would be greatly appreciated!

5 Answers 5

59
before_create :create_unique_identifier

def create_unique_identifier
  loop do
    self. unique_identifier = SecureRandom.hex(5) # or whatever you chose like UUID tools
    break unless self.class.exists?(:unique_identifier => unique_identifier)
  end
end
Sign up to request clarification or add additional context in comments.

Comments

10

Ruby 1.9 includes a built-in UUID generator: SecureRandom.uuid

Comments

5

1 Comment

I believe UUID was already known by the asker (see the q. text) ;). But +1 for the third link.
5

Another possiblity is to use SecureRandom.base64 which in comparison to hex additionally use capitalized letters and “+”, “/”, “=”. Documentation.

Example:

def generate_identifier
  begin
    uid = SecureRandom.base64(8)
  end while self.class.exists?(uid: uid)
  self.uid = uid
end

Comments

3

Save yourself the trouble from storing the obfuscated id and simply encode the id with base 62 (a-z, A-Z, 0-9) but custom define the order of the "digits". This will make it very complicated to figure out the order.

I once wrote something a class that does that (might need some refactoring): https://gist.github.com/4058176

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.