ruk·si

🛤️ Ruby on Rails
UUIDs as Model IDs

Updated at 2015-09-06 23:01

It's a good idea to use UUIDs as table primary keys.

  • Obfuscates the real count of rows.
  • Generating models at the same time don't generate collisions.
  • You are forced to create simpler URLs in contrast to the basic integer id.

Gem

Use ar-uuid and everything just works.

Doing It Yourself

rails g migration enable_uuid_ossp_extension
class EnableUuidOsspExtension < ActiveRecord::Migration
  def change
    enable_extension 'uuid-ossp'
  end
end
rails generate model document title:text author:text
class CreateDocuments < ActiveRecord::Migration
  def change
    create_table :documents, id: :uuid do |t|
      t.text :title
      t.text :author

      t.timestamps null: false
    end
  end
end

Default first and last don't work with UUID. But you can fix that.

class Document < ActiveRecord::Base
  scope :first, -> { order("created_at").first }
  scope :last, -> { order("created_at DESC").first }
end

Now all references must be explicitly typed as UUID.

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users, id: :uuid do |t|
      t.references :documents, type: :uuid, null: false, index: true
      # or
      # t.belongs_to :documents, type: :uuid, null: false, index: true
    end
  end
end

class AddDocumentReferenceToUsers < ActiveRecord::Migration
  def change
    add_reference :users, :documents, type: :uuid, index: true
  end
end

You can also create non-primary key fields as UUID.

t.uuid :api_key, null: false, default: 'uuid_generate_v4()'

You can generate UUIDs in Ruby too. Rarely required thing but good thing to have.

require 'securerandom'
SecureRandom.uuid

Sources