Skip to content

Instantly share code, notes, and snippets.

@spickermann
Created March 15, 2016 18:38
Show Gist options
  • Save spickermann/f8dd5eee523c96baac6c to your computer and use it in GitHub Desktop.
Save spickermann/f8dd5eee523c96baac6c to your computer and use it in GitHub Desktop.
Use in model with `include UUIDPrimaryKey`
RSpec.shared_examples 'a model with an uuid' do
subject(:instance) { FactoryGirl.create(described_class.name.downcase) }
it { should have_readonly_attribute(:id) }
describe '.find' do
it 'finds by uuid' do
expect(
described_class.find(instance.id)
).to eq(instance)
end
end
describe '#uuid' do
it 'is valid' do
expect(
instance.uuid
).to match(
# regexp that matches UUIDs Version 4 (random)
/\A[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}\z/
)
end
end
end
class UUIDIdentifier
attr_reader :uuid
def self.from_key(key)
uuid = "#{key[8..15]}-#{key[4..7]}-#{key[0..3]}-#{key[16..19]}-#{key[20..32]}"
new(UUIDTools::UUID.parse(uuid))
end
def initialize(uuid = nil)
@uuid = uuid || UUIDTools::UUID.random_create
end
def to_s
uuid.to_s
end
def to_key
s = to_s
"#{s[14..17]}#{s[9..12]}#{s[0..7]}#{s[19..22]}#{s[24..35]}"
end
end
require 'rails_helper'
RSpec.describe UUIDIdentifier do
let(:uuid_str) { '6ccd780c-baba-1026-9564-0040f4311e29' }
let(:uuid_key) { '1026baba6ccd780c95640040f4311e29' }
describe '.new' do
before do
allow(UUIDTools::UUID).to receive(:random_create).and_return(
UUIDTools::UUID.parse(uuid_str)
)
end
context 'without an UUID' do
it 'generates UUID and returns UUIDIdentifier' do
expect(UUIDIdentifier.new).to be_a(UUIDIdentifier)
expect(UUIDTools::UUID).to have_received(:random_create)
end
end
context 'with a UUID' do
let(:uuid) { UUIDTools::UUID.parse(uuid_str) }
it 'uses UUID and returns UUIDIdentifier' do
expect(UUIDIdentifier.new(uuid)).to be_a(UUIDIdentifier)
expect(UUIDTools::UUID).to_not have_received(:random_create)
end
end
end
describe '.parse' do
it 'returns UUIDIdentifier' do
identifier = UUIDIdentifier.from_key(uuid_key)
expect(identifier).to be_a(UUIDIdentifier)
expect(identifier.to_s).to eq(uuid_str)
end
end
describe '#to_key' do
let(:uuid) { UUIDTools::UUID.parse(uuid_str) }
it 'returns UUID key' do
identifier = UUIDIdentifier.new(uuid)
expect(identifier.to_key).to eq(uuid_key)
end
end
describe '#to_s' do
let(:uuid) { UUIDTools::UUID.parse(uuid_str) }
it 'returns UUID string' do
identifier = UUIDIdentifier.new(uuid)
expect(identifier.to_s).to eq(uuid_str)
end
end
end
require 'active_support/concern'
module UUIDPrimaryKey
extend ActiveSupport::Concern
included do
attr_readonly :id
before_create :ensure_id
def uuid
UUIDIdentifier.from_key(id).to_s
end
end
private def ensure_id
self.id ||= UUIDIdentifier.new.to_key
end
class_methods do
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment