diff --git a/lib/paranoia.rb b/lib/paranoia.rb index a2298953..954a49ef 100644 --- a/lib/paranoia.rb +++ b/lib/paranoia.rb @@ -2,6 +2,7 @@ module Paranoia @@default_sentinel_value = nil + @@default_recovery_window = nil # Change default_sentinel_value in a rails initializer def self.default_sentinel_value=(val) @@ -12,6 +13,14 @@ def self.default_sentinel_value @@default_sentinel_value end + def self.default_recovery_window=(val) + @@default_recovery_window = val + end + + def self.default_recovery_window + @@default_recovery_window + end + def self.included(klazz) klazz.extend Query klazz.extend Callbacks @@ -132,6 +141,7 @@ def restore!(opts = {}) def get_recovery_window_range(opts) return opts[:recovery_window_range] if opts[:recovery_window_range] + opts[:recovery_window] = paranoia_recovery_window if opts[:recovery_window].blank? && paranoia_recovery_window.present? return unless opts[:recovery_window] (deleted_at - opts[:recovery_window]..deleted_at + opts[:recovery_window]) end @@ -246,10 +256,12 @@ def self.acts_as_paranoid(options={}) alias_method :destroy_without_paranoia, :destroy include Paranoia - class_attribute :paranoia_column, :paranoia_sentinel_value + class_attribute :paranoia_column, :paranoia_sentinel_value, :paranoia_recovery_window self.paranoia_column = (options[:column] || :deleted_at).to_s self.paranoia_sentinel_value = options.fetch(:sentinel_value) { Paranoia.default_sentinel_value } + self.paranoia_recovery_window = options.fetch(:recovery_window) { Paranoia.default_recovery_window } + def self.paranoia_scope where(paranoia_column => paranoia_sentinel_value) end @@ -290,6 +302,10 @@ def paranoia_column def paranoia_sentinel_value self.class.paranoia_sentinel_value end + + def paranoia_recovery_window + self.class.paranoia_recovery_window + end end end diff --git a/test/paranoia_test.rb b/test/paranoia_test.rb index 8c4c2d3f..60a008da 100644 --- a/test/paranoia_test.rb +++ b/test/paranoia_test.rb @@ -230,6 +230,26 @@ def test_default_sentinel_value assert_nil ParanoidModel.paranoia_sentinel_value end + def test_default_sentinel_value_setter + ParanoidModel.paranoia_sentinel_value = 5 + assert_equal 5, ParanoidModel.paranoia_sentinel_value + ParanoidModel.paranoia_sentinel_value = nil + end + + def test_default_sentinel_value + assert_nil ParanoidModel.paranoia_sentinel_value + end + + def test_default_recovery_window_setter + ParanoidModel.paranoia_recovery_window = 5 + assert_equal 5, ParanoidModel.paranoia_recovery_window + ParanoidModel.paranoia_recovery_window = nil + end + + def test_default_recovery_window_value + assert_nil ParanoidModel.paranoia_recovery_window + end + def test_without_default_scope_option model = WithoutDefaultScopeModel.create model.destroy @@ -613,6 +633,38 @@ def test_restore_with_associations_using_recovery_window assert_equal true, second_child.reload.deleted_at.nil? end + def test_restore_with_associations_using_default_recovery_window + parent = ParentModelWithRecoveryWindow.create + first_child = parent.very_related_models.create + second_child = parent.very_related_models.create + + parent.destroy + second_child.update(deleted_at: parent.deleted_at + 11.minutes) + + parent.restore!(:recursive => true, recovery_window: 12.minutes) + assert_equal true, parent.deleted_at.nil? + assert_equal true, first_child.reload.deleted_at.nil? + assert_equal true, second_child.reload.deleted_at.nil? + + parent.destroy + second_child.update(deleted_at: parent.deleted_at + 11.minutes) + + parent.restore(:recursive => true) + assert_equal true, parent.deleted_at.nil? + assert_equal true, first_child.reload.deleted_at.nil? + assert_equal false, second_child.reload.deleted_at.nil? + + second_child.restore + parent.destroy + first_child.update(deleted_at: parent.deleted_at - 11.minutes) + second_child.update(deleted_at: parent.deleted_at - 9.minutes) + + ParentModelWithRecoveryWindow.restore(parent.id, :recursive => true) + assert_equal true, parent.reload.deleted_at.nil? + assert_equal false, first_child.reload.deleted_at.nil? + assert_equal true, second_child.reload.deleted_at.nil? + end + def test_restore_with_associations parent = ParentModel.create first_child = parent.very_related_models.create @@ -1050,7 +1102,6 @@ def get_featureful_model end # Helper classes - class ParanoidModel < ActiveRecord::Base belongs_to :parent_model acts_as_paranoid @@ -1120,6 +1171,18 @@ class ParentModel < ActiveRecord::Base has_one :polymorphic_model, as: :parent, dependent: :destroy end +class ParentModelWithRecoveryWindow < ActiveRecord::Base + self.table_name = 'parent_models' + acts_as_paranoid recovery_window: 10.minutes + has_many :paranoid_models, foreign_key: 'parent_model_id' + has_many :related_models, foreign_key: 'parent_model_id' + has_many :very_related_models, class_name: 'RelatedModel', foreign_key: 'parent_model_id', dependent: :destroy + has_many :non_paranoid_models, foreign_key: 'parent_model_id', dependent: :destroy + has_one :non_paranoid_model, foreign_key: 'parent_model_id', dependent: :destroy + has_many :asplode_models, foreign_key: 'parent_model_id', dependent: :destroy + has_one :polymorphic_model, as: :parent, dependent: :destroy +end + class ParentModelWithCounterCacheColumn < ActiveRecord::Base has_many :related_models end