Skip to content

Instantly share code, notes, and snippets.

@tamersalama
Created January 26, 2012 21:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tamersalama/1685185 to your computer and use it in GitHub Desktop.
Save tamersalama/1685185 to your computer and use it in GitHub Desktop.
Resourcing - Snapshotting
require_dependency 'acts_as_snapshot'
module ActsAsSnapshot
module ActiveRecord
def self.included(base)
base.extend(ActsAsSnapshot::ActiveRecord::ClassMethods)
end
module InstanceMethods
def assign_snapshot
self.snapshot = self.class.current_snapshot
end
def disable_save_for_old_snapshot
if !self.snapshot.blank?
self.errors.add(:base, "Can not update snapshot data")
return false
end
end
end
module ClassMethods
def acts_as_snapshot
include ActsAsSnapshot::ActiveRecord::InstanceMethods
before_create :assign_snapshot
if current_snapshot.blank?
default_scope :conditions => "#{self.table_name}.snapshot IS NULL"
else
default_scope :conditions => "#{self.table_name}.snapshot = #{self.current_snapshot}"
before_create :disable_save_for_old_snapshot
before_save :disable_save_for_old_snapshot
before_destroy :disable_save_for_old_snapshot
end
end
def current_snapshot
Thread.current[:snapshot_version]
end
def create_snapshot!(snapshot)
self.unscoped.where("snapshot IS NULL").all.each do |r|
new_r = r.clone
new_r.snapshot = snapshot
new_r.snapshot_parent_id = r.id
self.skip_callback(:create, :before, :assign_snapshot)
new_r.save!
self.set_callback(:create, :before, :assign_snapshot)
end
end
def rollback_snapshot!(snapshot)
self.unscoped.delete_all(["snapshot = ?", snapshot])
end
end
end
module SnapshotFilter
def self.included(base)
base.extend(ActsAsSnapshot::SnapshotFilter::ClassMethods)
end
module InstanceMethods
def current_snapshot
session[:version].blank? ? nil : session[:version].to_i
end
def assign_snapshot_version
old_version = session[:version]
if !params[:version].blank?
if params[:version].to_i == -1
session[:version] = nil
else
session[:version] = params[:version].to_i
end
end
new_version = session[:version]
Thread.current[:snapshot_version] = session[:version]
#force reloading the models to take set the default_scope according to the current thread
if new_version != old_version
[:bundle, :effort, :experience_level, :resource, :role, :vendor, :work_type, :app, :flight_risk, :vacation].each do |m|
obj_sym = m.to_s.classify.to_sym
if Object.const_defined?(obj_sym)
Object.send(:remove_const, obj_sym)
end
load "#{Rails.root}/app/models/#{m}.rb"
end
end
end
end
module ClassMethods
def set_snapshot
before_filter :assign_snapshot_version
include ActsAsSnapshot::SnapshotFilter::InstanceMethods
helper_method :current_snapshot
end
end
end
end
ActiveRecord::Base.send(:include, ActsAsSnapshot::ActiveRecord)
ActionController::Base.send(:include, ActsAsSnapshot::SnapshotFilter)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment