Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Mongoid
- module Undo
- extend ActiveSupport::Concern
- included do
- include Mongoid::Document
- field :version, type: Integer, default: 0
- before_save :prepare_versioning
- after_save :create_version
- before_destroy :version_destroy
- end
- def versions; ::Version.where(obj_id: id) end
- def versions_gt(version = self.version); versions.where(:version.gt => version) end
- def version_at(version = self.version); versions.where(version: version).first end
- def current_version; version_at end
- def previous_version; version_at version - 1 end
- def versioned?; version > 0 end
- def has?(ver)
- ver.obj_id == id && ver.obj_class == self.class.to_s
- end
- def matches?(ver)
- has?(ver) &&
- ver.obj_attributes == attributes &&
- ver.version == version
- end
- def undo!; rollback_to!(version - 1) end
- def rollback_to!(version)
- unless persisted?; return false end
- if version == 0
- versions.destroy
- without_versioning :destroy
- attributes
- else
- ver = version_at(version)
- unless ver; return false end
- ver.rollback_to(self)
- end
- end
- def without_versioning(method = nil)
- @without_versioning = true
- method ? method.to_proc.call(self) : yield
- ensure
- @without_versioning = false
- end
- private
- def match_persisted?
- current_version && attributes == current_version.obj_attributes
- end
- def prepare_versioning
- if !@without_versioning
- if version == 0 && persisted?
- self.version += 1
- old_self = self.class.find(id)
- old_self.version += 1
- old_self.send(:create_version)
- end
- if !match_persisted?; self.version += 1 end
- end
- end
- def create_version(destroy = false)
- if !@without_versioning && (destroy || !match_persisted?)
- ver = ::Version.new(obj_id: id, obj_class: self.class.to_s, version: version)
- unless destroy; ver.attributes = ver.attributes.merge({:obj_attributes => attributes}) end
- ver.save!
- end
- end
- def version_destroy
- if !@without_versioning
- self.version += 1
- without_versioning(:save)
- create_version(true)
- end
- end
- end
- end
Add Comment
Please, Sign In to add comment