/gold-record

ActiveRecord extension for unobtrusive binary UUIDs

Primary LanguageRubyMIT LicenseMIT

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.