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.
–
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
–
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.