Generate a UUID in Ruby

How to generate a UUID in Ruby: SecureRandom.uuid for v4, SecureRandom.uuid_v7 on Ruby 3.3, name based ids, validation with a regex, and Rails uuid primary keys on PostgreSQL and MySQL.

Try it here

Generate a UUID to paste into your Ruby code, in any version and format.

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.

    ↑ Top
    Copied!