GoldRecord

Unobtrusive binary UUIDs for ActiveRecord.

DESCRIPTION

GoldRecord is an extension for ActiveRecord that implements unobtrusive binary UUIDs in MySQL.

FEATURES

GoldRecord supports SchemaDumper by not declaring the id column a PRIMARY KEY. The odds of a random UUID collision are documented here.

  • Uses space-efficient 16-byte binary representation for UUIDs.

  • Works with associations, migrations and ActiveRecord::SchemaDumper.

  • Transparently converts to hex-encoded UUIDs in #to_param.

  • Transparently handles binary, hex-encoded and URL-safe Base64 UUIDs in #find.

SYNOPSIS

class Blog < ActiveRecord::Base
  acts_as_gold_record
  has_many :posts
end

class Post < ActiveRecord::Base
  acts_as_gold_record
end

Or, for the exceptionally paranoid:

class LargeHadron < ActiveRecord::Base
  acts_as_gold_record
  set_primary_key :lottery_number
  validates_uniqueness_of :lottery_number, :on => :create
end

FIXTURES

# In test/helper.rb or spec_helper.rb:
require 'active_record/fixtures'
Fixtures.send :include, GoldRecord::Fixtures

MIGRATIONS

class MakeGoldRecords < ActiveRecord::Migration
  TABLES = [:labels, :record_stores]
  ASSOCIATIONS = [
    [:artists, :label_id, :id],
    [:labels_record_stores, :label_id, false],
    [:labels_record_stores, :record_store_id, false],
    [:artists_record_stores, :record_store_id, false],
  ]

  def self.up
    # Change each int(11) id column to binary(16).
    # This preserves the column’s original value as a right-padded 16-byte string.
    TABLES.each do |table|
      change_integer_primary_key_to_uuid(table)
      add_index table, :id
    end

    # Change association columns to binary(16).
    ASSOCIATIONS.each do |table, column, primary_key|
      change_integer_to_uuid(table, column, primary_key)
    end
  end

  # Down migration designed to be run immediately after an up migration
  # in the event of some failure. Running this after generating any UUIDs
  # will produce unpredictable results.

  def self.down
    # Change each binary(16) id column to int(11).
    # MySQL casts the string value to an integer.
    TABLES.each do |table|
      remove_index table, :id
      change_uuid_to_integer_primary_key(table)
    end

    # Change association columns to int(11).
    ASSOCIATIONS.each do |table, column|
      change_uuid_to_integer(table, column, primary_key)
    end
  end
end

INSTALL

As a gem:

[sudo] gem install gold-record

As a Rails plugin:

Clone/copy to vendor/plugins/gold_record.