Skip to content

Instantly share code, notes, and snippets.

@thillerson
Created May 20, 2009 15:48
Show Gist options
  • Save thillerson/114891 to your computer and use it in GitHub Desktop.
Save thillerson/114891 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'uuidtools'
module UUIDasID
#
# When included, e.g. <code>include UUIDasID</code>,
# this method will be called, passing the class in
#
def self.included mod
# this will set up generate_uuid as a before_create callback
mod.instance_eval( %q{before_create :generate_uuid} )
# here we define the macro method, has_uuid, and a query method, has_uuid?
mod.class_eval do
def self.has_uuid column_name, options={}
@has_uuid = true
@uuid_options = options.merge(:id => column_name)
end
def self.has_uuid?
@has_uuid || false
end
end
end
#
# This method is called whenever an ActiveRecord is created
# but should fail early if has_uuid wasn't called as a macro
# e.g. <code>has_uuid :guid, :unique_with => [:attr1, attr2]</code>
#
def generate_uuid
# fail early and quietly if this AR doesn't have a UUID
return true unless self.class.has_uuid?
options = self.class.instance_variable_get :@uuid_options
# this could help with testing
return true unless send("#{options[:id]}").nil?
# get each attribute that makes this record unique and make an array of string values
unique_attributes = options[:unique_with].inject([Time.new.to_s]) do |atts, current_att_name|
atts << send("#{current_att_name}").to_s
end rescue ['nuffin'] # or just make a dummy string array
# set the id to a SHA1 of the timestamp plus unique values (minus the dashes)
uuid = UUID.sha1_create(UUID_DNS_NAMESPACE, unique_attributes.join('')).to_s.gsub(/-/, '')
send("#{options[:id]}=", uuid)
# if the callback method uuid_generated exists, call it with the new uuid
uuid_generated(send("#{options[:id]}")) if respond_to?(:uuid_generated)
true
end
end
#
# Go on and put this feller on all ActiveRecords, at least once it's required
# maybe it will be a plugin someday
#
class ActiveRecord::Base
include UUIDasID
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment