
Untitled
By: a guest on
Aug 3rd, 2012 | syntax:
None | size: 1.42 KB | hits: 12 | expires: Never
module Versionable
extend ActiveSupport::Concern
BASE_VERSION = 1
VERSION_PROPERTY_NAME = 'schema_version'
included do
property VERSION_PROPERTY_NAME.to_sym, Integer, numericality: { greater_than_or_equal_to: 0 }, default: lambda { current_schema_version }
extend (embeddable? ? EmbeddedDocument : Document)
end
module ClassMethods
attr_accessor :migrate_schema_block
def migrate_schema(&block)
self.migrate_schema_block = block
end
def current_schema_version(version = nil)
if version
@_current_schema_version = version
else
@_current_schema_version or raise "current_schema_version is not set"
end
end
private
def instantiate(robject_or_hash, data)
super(robject_or_hash).tap do |document|
if document.schema_version < current_schema_version && migrate_schema_block
document.instance_exec(data, &migrate_schema_block)
elsif document.schema_version > current_schema_version
raise "Cannot migrate #{self} from version #{document.schema_version} to #{current_schema_version}"
end
end
end
end
module Document
private
def instantiate(robject)
robject.data[VERSION_PROPERTY_NAME] ||= BASE_VERSION
super(robject, robject.data)
end
end
module EmbeddedDocument
def instantiate(hash)
hash[VERSION_PROPERTY_NAME] ||= BASE_VERSION
super(hash, hash)
end
end
end