module SoftDeletion::Core
Public Class Methods
included(base)
click to toggle source
# File lib/soft_deletion/core.rb, line 3 def self.included(base) unless base.ancestors.include?(ActiveRecord::Base) raise "You can only include this if #{base} extends ActiveRecord::Base" end base.extend(ClassMethods) base.define_model_callbacks :soft_delete base.define_model_callbacks :soft_undelete base.cattr_accessor :soft_delete_default_scope end
Public Instance Methods
deleted?()
click to toggle source
# File lib/soft_deletion/core.rb, line 55 def deleted? deleted_at.present? end
mark_as_deleted()
click to toggle source
# File lib/soft_deletion/core.rb, line 59 def mark_as_deleted self.deleted_at ||= Time.now end
mark_as_undeleted()
click to toggle source
# File lib/soft_deletion/core.rb, line 63 def mark_as_undeleted self.deleted_at = nil end
soft_delete(*args)
click to toggle source
# File lib/soft_deletion/core.rb, line 71 def soft_delete(*args) _run_soft_delete(:soft_delete, args) { save(*args) } end
soft_delete!(*args)
click to toggle source
# File lib/soft_deletion/core.rb, line 67 def soft_delete!(*args) _run_soft_delete(:soft_delete!, args) { save!(*args) } || soft_delete_hook_failed(:before_soft_delete) end
soft_delete_dependencies()
click to toggle source
# File lib/soft_deletion/core.rb, line 83 def soft_delete_dependencies self.class.soft_delete_dependents.map { |dependent| SoftDeletion::Dependency.new(self, dependent) } end
soft_undelete()
click to toggle source
# File lib/soft_deletion/core.rb, line 75 def soft_undelete _run_soft_undelete{ save } end
soft_undelete!()
click to toggle source
# File lib/soft_deletion/core.rb, line 79 def soft_undelete! _run_soft_undelete{ save! } || soft_delete_hook_failed(:before_soft_undelete) end
Protected Instance Methods
_run_soft_delete(method, args, &block)
click to toggle source
# File lib/soft_deletion/core.rb, line 99 def _run_soft_delete(method, args, &block) result = false self.class.transaction do internal = lambda do mark_as_deleted raise ActiveRecord::Rollback unless soft_delete_dependencies.all? { |dep| dep.execute_soft_delete(method, args) } result = block.call raise ActiveRecord::Rollback unless result update_soft_delete_counter_caches(-1) end run_callbacks :soft_delete, &internal result end result end
_run_soft_undelete(&block)
click to toggle source
# File lib/soft_deletion/core.rb, line 117 def _run_soft_undelete(&block) raise "#{self.class} is not deleted" unless deleted_at result = false limit = deleted_at - 1.hour internal = lambda do mark_as_undeleted soft_delete_dependencies.each { |m| m.soft_undelete!(limit) } result = block.call update_soft_delete_counter_caches(1) end self.class.transaction do run_callbacks :soft_undelete, &internal end result end
soft_delete_hook_failed(hook)
click to toggle source
# File lib/soft_deletion/core.rb, line 136 def soft_delete_hook_failed(hook) error = (errors.full_messages.presence || ["None"]).join(", ") message = "#{hook} hook failed, errors: #{error}" # not passing record (self) as 2nd argument to be rails 3/4.1 compatible raise ActiveRecord::RecordNotSaved.new(message) end
update_soft_delete_counter_caches(value)
click to toggle source
# File lib/soft_deletion/core.rb, line 89 def update_soft_delete_counter_caches(value) each_counter_cached_associations do |association| association.load_target unless association.loaded? if association.target target = association.target target.class.update_counters(target.id, association.reflection.counter_cache_column => value) end end end