Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm attributing a unique code to each created item, to use in the URL. I do this during the item creation in the model:

class Item < ActiveRecord::Base
  before_create { self.code = SecureRandom.urlsafe_base64 }

But I don't know if the generated code is really unique. Do I have to check the uniqueness during the creation, but this can take unnecessary time and resources if the Items table grows:

before_create :generate_unique_code
def generate_unique_code
  loop do
    code = SecureRandom.urlsafe_base64
    unless Item.where(:code => code).any?
      self.code = code
      break

Can I trust the uniqueness of SecureRandom.urlsafe_base64 and skip the check?

Nothing is completely random in a computer generated string. Technically, there is a very low, remote possibility that two strings may be the same.

This is even more true in a highly concurrent system. If that's not the case, what you can do is to simply add an unique constraint (aka an unique index) at the database level. In this way, in the remote event that two strings will be equal, the database will reject the second one.

It's likely you will have an index on that field in any case if you need to use it for a query, therefore it should not add any unreasonable overhead.

As a side note, SecureRandom is a Ruby library, not a Rails library.

Thanks for your reply (and question edits) Simone. You're right, I'll add the index constraint to the attribute. – Hassen Jun 17, 2015 at 10:36

In order for it to be unique, it either has to (i) be following a rule that makes it never hit a previously generated output (such as by calling a one-to-one function on the time it was called, which only works under single thread), which makes it non-random, or (ii) keep a record of all previously generated outputs somewhere, which cannot be the case, and which also makes it non-random. In either case, you should be able to tell that is cannot be unique.

However, mathematics and engineering are different. Even if it is not unique, you can regard it as de facto unique. That is what programmers do.

Rails master branch includes one new module related to this. https://github.com/rails/rails/blob/master/activerecord/lib/active_record/secure_token.rb

Another solution you can reference.

Generating unique token on the fly with Rails

The module you referenced in the Rails core still doesn't validate uniqueness of the token. It assumes the generated token is unique. – Simone Carletti Jun 17, 2015 at 12:17

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.