Update Oct 2020:
Don't try to be clever. A UUID is more than enough, they're cheap and fast to generate, forget about collisions, other failures are way (way WAY!!) more likely. The idea behind UUIDs, interesting stuff.
require 'securerandom'
SecureRandom.uuid
#=> "a62f45ba-292d-425b-fb49-3733b00defe1"
Old answer:
Very simple actually:
enum = [*'a'..'z', *'A'..'Z', *0..9].shuffle.permutation
enum.next.join
=> "qmrbSTBu6gGpMs4Jh0VZAiI9cW58jxoDz2NwL1eUClaFtdRXfPEOYQnvkKy7H3"
This provides
factorial(62)
uniq strings/uids. (A very large number!)
You can also provide a limit to permutation
if you want shorter strings/uids, however this will decrease the amount of uniq strings/uids you can generate.
enum = [*'a'..'z', *'A'..'Z', *0..9].shuffle.permutation(13)
enum.next.join
=> "A1BD3qljTKpOm"
If you're concern about security, then, shuffle the array with a secure random seed:
ary = [*'a'..'z', *'A'..'Z', *0..9].shuffle(random: SecureRandom.hex(23).to_i(16))
enum = ary.permutation(13)
enum.next.join
=> "9bNmv82ruBKjq"
Uniqueness is guarantee (thus limited), without the overhead of calling a database or testing uniqueness.