lib/vestal_versions/version.rb in vestal_versions-1.0.2 vs lib/vestal_versions/version.rb in vestal_versions-2.0.0
- old
+ new
@@ -1,19 +1,30 @@
+require 'active_record'
+require 'active_support/configurable'
+
module VestalVersions
# The ActiveRecord model representing versions.
class Version < ActiveRecord::Base
include Comparable
+ include ActiveSupport::Configurable
# Associate polymorphically with the parent record.
belongs_to :versioned, :polymorphic => true
+ if ActiveRecord::VERSION::MAJOR == 3
+ attr_accessible :modifications, :number, :user, :tag, :reverted_from
+ end
+
# ActiveRecord::Base#changes is an existing method, so before serializing the +changes+ column,
- # the existing +changes+ method is undefined. The overridden +changes+ method pertained to
+ # the existing +changes+ method is undefined. The overridden +changes+ method pertained to
# dirty attributes, but will not affect the partial updates functionality as that's based on
# an underlying +changed_attributes+ method, not +changes+ itself.
undef_method :changes
- serialize :changes, Hash
+ def changes
+ self[:modifications]
+ end
+ serialize :modifications, Hash
# In conjunction with the included Comparable module, allows comparison of version records
# based on their corresponding version numbers, creation timestamps and IDs.
def <=>(other)
[number, created_at, id].map(&:to_i) <=> [other.number, other.created_at, other.id].map(&:to_i)
@@ -22,8 +33,52 @@
# Returns whether the version has a version number of 1. Useful when deciding whether to ignore
# the version during reversion, as initial versions have no serialized changes attached. Helps
# maintain backwards compatibility.
def initial?
number == 1
+ end
+
+ # Returns the original version number that this version was.
+ def original_number
+ if reverted_from.nil?
+ number
+ else
+ version = versioned.versions.at(reverted_from)
+ version.nil? ? 1 : version.original_number
+ end
+ end
+
+ def restore!
+ model = restore
+
+ if model
+ model.save!
+ destroy
+ end
+
+ model
+ end
+
+ def restore
+ if tag == 'deleted'
+ attrs = modifications
+
+ class_name = attrs['type'].blank? ? versioned_type : attrs['type']
+ klass = class_name.constantize
+ model = klass.new
+
+ attrs.each do |k, v|
+ begin
+ model.send "#{k}=", v
+ rescue NoMethodError
+ logger.warn "Attribute #{k} does not exist on #{class_name} (Version id: #{id})." rescue nil
+ end
+ end
+
+ model
+ else
+ latest_version = self.class.where(:versioned_id => versioned_id, :versioned_type => versioned_type, :tag => 'deleted').first
+ latest_version.nil? ? nil : latest_version.restore
+ end
end
end
end