module Kumolus::Paranoia
Constants
- VERSION
Public Class Methods
default_sentinel_value()
click to toggle source
# File lib/kumolus/paranoia.rb, line 13 def self.default_sentinel_value @@default_sentinel_value end
default_sentinel_value=(val)
click to toggle source
Change default_sentinel_value
in a rails initializer
# File lib/kumolus/paranoia.rb, line 9 def self.default_sentinel_value=(val) @@default_sentinel_value = val end
included(klazz)
click to toggle source
# File lib/kumolus/paranoia.rb, line 17 def self.included(klazz) klazz.extend Query klazz.extend Callbacks end
Public Instance Methods
delete()
click to toggle source
# File lib/kumolus/paranoia.rb, line 96 def delete raise ActiveRecord::ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly? if persisted? # if a transaction exists, add the record so that after_commit # callbacks can be run add_to_transaction update_columns(paranoia_destroy_attributes) elsif !frozen? assign_attributes(paranoia_destroy_attributes) end self end
destroy()
click to toggle source
# File lib/kumolus/paranoia.rb, line 78 def destroy transaction do run_callbacks(:destroy) do @_disable_counter_cache = deleted? result = delete next result unless result && ActiveRecord::VERSION::STRING >= '4.2' each_counter_cached_associations do |association| foreign_key = association.reflection.foreign_key.to_sym next if destroyed_by_association && destroyed_by_association.foreign_key.to_sym == foreign_key next unless send(association.reflection.name) association.decrement_counters end @_disable_counter_cache = false result end end end
get_recovery_window_range(opts)
click to toggle source
# File lib/kumolus/paranoia.rb, line 135 def get_recovery_window_range(opts) return opts[:recovery_window_range] if opts[:recovery_window_range] return unless opts[:recovery_window] (deleted_at - opts[:recovery_window]..deleted_at + opts[:recovery_window]) end
paranoia_destroyed?()
click to toggle source
# File lib/kumolus/paranoia.rb, line 146 def paranoia_destroyed? send(paranoia_column) != paranoia_sentinel_value end
Also aliased as: is_deleted?
really_destroy!()
click to toggle source
# File lib/kumolus/paranoia.rb, line 151 def really_destroy! transaction do run_callbacks(:real_destroy) do @_disable_counter_cache = deleted? dependent_reflections = self.class.reflections.select do |name, reflection| reflection.options[:dependent] == :destroy end if dependent_reflections.any? dependent_reflections.each do |name, reflection| association_data = self.send(name) # has_one association can return nil # .paranoid? will work for both instances and classes next unless association_data && association_data.paranoid? if reflection.collection? next association_data.with_deleted.each(&:really_destroy!) end association_data.really_destroy! end end write_attribute(paranoia_column, current_time_from_proper_timezone) destroy_without_paranoia end end end
restore!(opts = {})
click to toggle source
# File lib/kumolus/paranoia.rb, line 109 def restore!(opts = {}) self.class.transaction do run_callbacks(:restore) do recovery_window_range = get_recovery_window_range(opts) # Fixes a bug where the build would error because attributes were frozen. # This only happened on Rails versions earlier than 4.1. noop_if_frozen = ActiveRecord.version < Gem::Version.new("4.1") if within_recovery_window?(recovery_window_range) && ((noop_if_frozen && !@attributes.frozen?) || !noop_if_frozen) @_disable_counter_cache = !deleted? write_attribute paranoia_column, paranoia_sentinel_value update_columns(paranoia_restore_attributes) each_counter_cached_associations do |association| if send(association.reflection.name) association.increment_counters end end @_disable_counter_cache = false end restore_associated_records(recovery_window_range) if opts[:recursive] end end self end
Also aliased as: restore
within_recovery_window?(recovery_window_range)
click to toggle source
# File lib/kumolus/paranoia.rb, line 141 def within_recovery_window?(recovery_window_range) return true unless recovery_window_range recovery_window_range.cover?(deleted_at) end
Private Instance Methods
each_counter_cached_associations()
click to toggle source
Calls superclass method
# File lib/kumolus/paranoia.rb, line 178 def each_counter_cached_associations !@_disable_counter_cache && defined?(super) ? super : [] end
paranoia_destroy_attributes()
click to toggle source
# File lib/kumolus/paranoia.rb, line 188 def paranoia_destroy_attributes { paranoia_column => current_time_from_proper_timezone }.merge(timestamp_attributes_with_current_time) end
paranoia_restore_attributes()
click to toggle source
# File lib/kumolus/paranoia.rb, line 182 def paranoia_restore_attributes { paranoia_column => paranoia_sentinel_value }.merge(timestamp_attributes_with_current_time) end
restore_associated_records(recovery_window_range = nil)
click to toggle source
restore associated records that have been soft deleted when we called destroy
# File lib/kumolus/paranoia.rb, line 200 def restore_associated_records(recovery_window_range = nil) destroyed_associations = self.class.reflect_on_all_associations.select do |association| association.options[:dependent] == :destroy end destroyed_associations.each do |association| association_data = send(association.name) unless association_data.nil? if association_data.paranoid? if association.collection? association_data.only_deleted.each do |record| record.restore(:recursive => true, :recovery_window_range => recovery_window_range) end else association_data.restore(:recursive => true, :recovery_window_range => recovery_window_range) end end end if association_data.nil? && association.macro.to_s == "has_one" association_class_name = association.klass.name association_foreign_key = association.foreign_key if association.type association_polymorphic_type = association.type association_find_conditions = { association_polymorphic_type => self.class.name.to_s, association_foreign_key => self.id } else association_find_conditions = { association_foreign_key => self.id } end association_class = association_class_name.constantize if association_class.paranoid? association_class.only_deleted.where(association_find_conditions).first .try!(:restore, recursive: true, :recovery_window_range => recovery_window_range) end end end clear_association_cache if destroyed_associations.present? end
timestamp_attributes_with_current_time()
click to toggle source
# File lib/kumolus/paranoia.rb, line 194 def timestamp_attributes_with_current_time timestamp_attributes_for_update_in_model.each_with_object({}) { |attr,hash| hash[attr] = current_time_from_proper_timezone } end