Try it here
Generate a UUID to paste into your Ruby code, in any version and format.
Your UUIDs
Copy one, copy them all, or download the list. The format options above apply to everything shown here.
The standard library: SecureRandom
require "securerandom"
SecureRandom.uuid # "f47ac10b-58cc-4372-a567-0e02b2c3d479", version 4
SecureRandom.uuid_v4 # same, Ruby 3.3+
SecureRandom.uuid_v7 # time ordered v7, Ruby 3.3+
SecureRandom reads from the operating system's secure random source. uuid_v7 arrived in Ruby 3.3 and is what you want for primary keys, see the v7 page. On Ruby 3.2 and older, the uuid7 gem provides the same call.
Name based UUIDs
The standard library has no v5. Either use the uuidtools gem or build it from Digest.
require "digest"
NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
def uuid_v5(namespace, name)
ns = [namespace.delete("-")].pack("H*")
h = Digest::SHA1.digest(ns + name).bytes.first(16)
h[6] = (h[6] & 0x0f) | 0x50 # version 5
h[8] = (h[8] & 0x3f) | 0x80 # variant RFC
h.pack("C*").unpack1("H*").sub(/(.{8})(.{4})(.{4})(.{4})(.{12})/, '\1-\2-\3-\4-\5')
end
uuid_v5(NAMESPACE_DNS, "example.com") # "cfbff0d1-9375-5685-968c-48ce8b15ae17"
Validate
UUID_RE = /\A\h{8}-\h{4}-[1-8]\h{3}-[89ab]\h{3}-\h{12}\z/i
def uuid?(value)
value.is_a?(String) && UUID_RE.match?(value)
end
Use \A and \z, not ^ and $. In Ruby the latter match line boundaries, so a value with a newline and junk after it would pass.
Rails
# PostgreSQL: native uuid column, generated by the database
create_table :orders, id: :uuid do |t|
t.string :status
end
# in config/initializers/generators.rb to make it the default for every table
Rails.application.config.generators { |g| g.orm :active_record, primary_key_type: :uuid }
# MySQL has no uuid type, so generate in Ruby and store as a string or binary
class Order < ApplicationRecord
before_create { self.id ||= SecureRandom.uuid_v7 }
end
On PostgreSQL 18 you can set the column default to uuidv7() in the migration for time ordered keys generated by the database.
Mistakes to avoid
- SecureRandom.hex(16) is not a UUID. It is 32 random hex characters with no version or variant bits. It will fail strict validators.
- rand and Random.new for ids. Not secure. SecureRandom only.
- Rails ordering by a uuid v4 primary key. Random keys give random order. Add a created_at index, or use v7 keys.
Frequently asked questions
Is SecureRandom.uuid a v4 UUID?
Yes. It is 122 random bits from the OS with the version and variant bits set, identical to any other v4.
How do I generate a UUID v7 in Ruby?
SecureRandom.uuid_v7 on Ruby 3.3 or newer. On older versions add the uuid7 gem.
Should Rails primary keys be UUIDs?
On PostgreSQL it is a good default for anything exposed in URLs or merged across environments. Use v7 where you can so inserts stay ordered. On MySQL it works but takes more care, since there is no native uuid type.