From 60c236e32a09fbeba0996a40c251cffa2dbcbae6 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Tue, 6 Aug 2013 15:15:40 -0700 Subject: [PATCH 001/105] Fixing cascading recover to recover the main model first and then its dependents --- lib/acts_as_paranoid/core.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index c081abc..74b8854 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -124,15 +124,17 @@ def recover(options={}) self.class.transaction do run_callbacks :recover do - recover_dependent_associations(options[:recovery_window], options) if options[:recursive] + paranoid_original_value = self.paranoid_value self.paranoid_value = nil - self.save + self.save! + + recover_dependent_associations(paranoid_original_value, options[:recovery_window], options) if options[:recursive] end end end - def recover_dependent_associations(window, options) + def recover_dependent_associations(paranoid_original_value, window, options) self.class.dependent_associations.each do |reflection| next unless (klass = get_reflection_class(reflection)).paranoid? @@ -144,7 +146,7 @@ def recover_dependent_associations(window, options) # We can only recover by window if both parent and dependant have a # paranoid column type of :time. if self.class.paranoid_column_type == :time && klass.paranoid_column_type == :time - scope = scope.merge(klass.deleted_inside_time_window(paranoid_value, window)) + scope = scope.merge(reflection.klass.deleted_inside_time_window(paranoid_original_value, window)) end scope.each do |object| From 0c692d2b613801ee58ca6b30f3eb58dc5de0d107 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 24 Feb 2014 03:04:24 -0800 Subject: [PATCH 002/105] Remove Gemfile.lock from repository --- .gitignore | 1 + Gemfile.lock | 41 ----------------------------------------- 2 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore index 9248ddd..176876d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ pkg .bundle .DS_Store +Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 36157bd..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,41 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - activemodel (3.2.3) - activesupport (= 3.2.3) - builder (~> 3.0.0) - activerecord (3.2.3) - activemodel (= 3.2.3) - activesupport (= 3.2.3) - arel (~> 3.0.2) - tzinfo (~> 0.3.29) - activerecord-jdbc-adapter (1.2.9.1) - activerecord-jdbcsqlite3-adapter (1.2.9) - activerecord-jdbc-adapter (~> 1.2.9) - jdbc-sqlite3 (~> 3.7.2) - activesupport (3.2.3) - i18n (~> 0.6) - multi_json (~> 1.0) - arel (3.0.2) - autotest-growl (0.2.16) - builder (3.0.0) - i18n (0.6.0) - jdbc-sqlite3 (3.7.2.1) - minitest (2.12.1) - multi_json (1.3.4) - rake (0.9.2.2) - sqlite3 (1.3.6) - tzinfo (0.3.33) - -PLATFORMS - java - ruby - -DEPENDENCIES - activerecord (~> 3.2) - activerecord-jdbcsqlite3-adapter - activesupport (~> 3.2) - autotest-growl - minitest - rake - sqlite3 From 9e6ee17f59151337bfe49982f70a55b8a1438277 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 24 Feb 2014 03:06:47 -0800 Subject: [PATCH 003/105] Resolve warning about rake/rdoctask --- Rakefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index cd2d548..179ffd7 100755 --- a/Rakefile +++ b/Rakefile @@ -5,11 +5,10 @@ rescue LoadError $stderr.puts "You need to have Bundler installed to be able build this gem." end require "rake/testtask" -require "rake/rdoctask" +require "rdoc/task" gemspec = eval(File.read(Dir["*.gemspec"].first)) - desc 'Default: run unit tests.' task :default => :test From 0d5956f2dc64fe2467e0640d8a445fe8dc0555e9 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 24 Feb 2014 03:09:18 -0800 Subject: [PATCH 004/105] Move test dependencies into gemspec as development dependencies --- Gemfile | 5 ----- acts_as_paranoid.gemspec | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 2f3cc40..e970d10 100644 --- a/Gemfile +++ b/Gemfile @@ -13,8 +13,3 @@ end platforms :jruby do gem "activerecord-jdbcsqlite3-adapter" end - -group :test do - gem "minitest" - gem "autotest-growl" -end diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index a6d792a..b56e0e4 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -13,5 +13,8 @@ Gem::Specification.new do |s| s.add_dependency "activerecord", "~> 3.2" + s.add_development_dependency "minitest" + s.add_development_dependency 'rake', ['>= 0'] + s.files = Dir["{lib}/**/*.rb", "LICENSE", "*.markdown"] end From d6d46994f9e8006e9703f2f11282f2315fab302c Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 24 Feb 2014 03:12:07 -0800 Subject: [PATCH 005/105] Support activerecord >= 4.0.0 --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index b56e0e4..f03f8c0 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = ">= 1.3.6" - s.add_dependency "activerecord", "~> 3.2" + s.add_dependency "activerecord", ">= 4.0.0" s.add_development_dependency "minitest" s.add_development_dependency 'rake', ['>= 0'] From 631ffaf4ea95792d2ef42468c469e928fdac9a2f Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 24 Feb 2014 03:12:43 -0800 Subject: [PATCH 006/105] bump gem to 0.5.0 --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index f03f8c0..3a1e2b6 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "acts_as_paranoid" - s.version = "0.0.0" + s.version = "0.5.0" s.platform = Gem::Platform::RUBY s.authors = ["Goncalo Silva", "Charles G.", "Rick Olson"] s.email = ["goncalossilva@gmail.com"] From 587074bf9e68e4961241e61f060ceb11ebe9e945 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 24 Feb 2014 03:12:54 -0800 Subject: [PATCH 007/105] Update gemspec summary and description to remove dependency mention. We can announce maintenance policy in README. --- acts_as_paranoid.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 3a1e2b6..1502885 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -5,8 +5,8 @@ Gem::Specification.new do |s| s.authors = ["Goncalo Silva", "Charles G.", "Rick Olson"] s.email = ["goncalossilva@gmail.com"] s.homepage = "https://github.com/goncalossilva/rails3_acts_as_paranoid" - s.summary = "Active Record (~>3.2) plugin which allows you to hide and restore records without actually deleting them." - s.description = "Active Record (~>3.2) plugin which allows you to hide and restore records without actually deleting them. Check its GitHub page for more in-depth information." + s.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." + s.description = "Active Record plugin which allows you to hide and restore records without actually deleting them. Check its GitHub page for more in-depth information." s.rubyforge_project = s.name s.required_rubygems_version = ">= 1.3.6" From 9de04abe0976c13906d06dbb53dd751e7f5693a8 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 24 Feb 2014 03:14:38 -0800 Subject: [PATCH 008/105] Add gemfile support for testing against various versions of activerecord on travis. --- .gitignore | 1 + .travis.yml | 16 +++++++++++++--- gemfiles/active_record_40.gemfile | 13 +++++++++++++ gemfiles/active_record_41.gemfile | 15 +++++++++++++++ gemfiles/active_record_edge.gemfile | 15 +++++++++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 gemfiles/active_record_40.gemfile create mode 100644 gemfiles/active_record_41.gemfile create mode 100644 gemfiles/active_record_edge.gemfile diff --git a/.gitignore b/.gitignore index 176876d..da57012 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ pkg .bundle .DS_Store Gemfile.lock +gemfiles/*.lock diff --git a/.travis.yml b/.travis.yml index 736d1b5..611987a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,16 @@ language: ruby rvm: - - 1.9.2 - 1.9.3 - - jruby-19mode - - rbx-19mode + - 2.0.0 + - 2.1.0 + - jruby + - rbx +gemfile: + - gemfiles/active_record_40.gemfile + - gemfiles/active_record_41.gemfile + - gemfiles/active_record_edge.gemfile +matrix: + allow_failures: + - rvm: rbx + - rvm: jruby + fast_finish: true diff --git a/gemfiles/active_record_40.gemfile b/gemfiles/active_record_40.gemfile new file mode 100644 index 0000000..40183ef --- /dev/null +++ b/gemfiles/active_record_40.gemfile @@ -0,0 +1,13 @@ +source 'https://rubygems.org' + +gem 'activerecord', '~> 4.0.0', :require => 'active_record' +gem 'activesupport', '~> 4.0.0', :require => 'active_record' + +platforms :ruby, :rbx do + gem 'sqlite3' +end +platforms :jruby do + gem 'activerecord-jdbcsqlite3-adapter' +end + +gemspec :path => '../' diff --git a/gemfiles/active_record_41.gemfile b/gemfiles/active_record_41.gemfile new file mode 100644 index 0000000..2908b56 --- /dev/null +++ b/gemfiles/active_record_41.gemfile @@ -0,0 +1,15 @@ +source 'https://rubygems.org' + +git 'git://github.com/rails/rails.git', :branch => '4-1-stable' do + gem 'activerecord', :require => 'active_record' + gem 'activesupport', :require => 'active_record' +end + +platforms :ruby, :rbx do + gem 'sqlite3' +end +platforms :jruby do + gem 'activerecord-jdbcsqlite3-adapter' +end + +gemspec :path => '../' diff --git a/gemfiles/active_record_edge.gemfile b/gemfiles/active_record_edge.gemfile new file mode 100644 index 0000000..a8c30ab --- /dev/null +++ b/gemfiles/active_record_edge.gemfile @@ -0,0 +1,15 @@ +source 'https://rubygems.org' + +git 'git://github.com/rails/rails.git' do + gem 'activerecord', :require => 'active_record' + gem 'activesupport', :require => 'active_record' +end + +platforms :ruby, :rbx do + gem 'sqlite3' +end +platforms :jruby do + gem 'activerecord-jdbcsqlite3-adapter' +end + +gemspec :path => '../' From c24aefd4e594234ba887a502483f5936e04e5de0 Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 21:54:03 +0100 Subject: [PATCH 009/105] Fix trailing spaces on files. --- lib/acts_as_paranoid.rb | 16 ++++---- lib/acts_as_paranoid/core.rb | 4 +- lib/acts_as_paranoid/relation.rb | 4 +- test/test_associations.rb | 4 +- test/test_core.rb | 66 ++++++++++++++++---------------- test/test_default_scopes.rb | 2 +- test/test_helper.rb | 58 ++++++++++++++-------------- test/test_inheritance.rb | 3 +- test/test_observers.rb | 2 +- test/test_relations.rb | 8 ++-- test/test_validations.rb | 10 ++--- 11 files changed, 88 insertions(+), 89 deletions(-) diff --git a/lib/acts_as_paranoid.rb b/lib/acts_as_paranoid.rb index e766c06..ef12798 100644 --- a/lib/acts_as_paranoid.rb +++ b/lib/acts_as_paranoid.rb @@ -8,20 +8,20 @@ module ActsAsParanoid - + def paranoid? self.included_modules.include?(ActsAsParanoid::Core) end - + def validates_as_paranoid include ActsAsParanoid::Validations end - + def acts_as_paranoid(options = {}) raise ArgumentError, "Hash expected, got #{options.class.name}" if not options.is_a?(Hash) and not options.empty? - + class_attribute :paranoid_configuration, :paranoid_column_reference - + self.paranoid_configuration = { :column => "deleted_at", :column_type => "time", :recover_dependent_associations => true, :dependent_recovery_window => 2.minutes } self.paranoid_configuration.merge!({ :deleted_value => "deleted" }) if options[:column_type] == "string" self.paranoid_configuration.merge!(options) # user options @@ -29,11 +29,11 @@ def acts_as_paranoid(options = {}) raise ArgumentError, "'time', 'boolean' or 'string' expected for :column_type option, got #{paranoid_configuration[:column_type]}" unless ['time', 'boolean', 'string'].include? paranoid_configuration[:column_type] self.paranoid_column_reference = "#{self.table_name}.#{paranoid_configuration[:column]}" - + return if paranoid? - + include ActsAsParanoid::Core - + # Magic! default_scope { where(paranoid_default_scope_sql) } diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index c081abc..3aa3c34 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -131,7 +131,7 @@ def recover(options={}) end end end - + def recover_dependent_associations(window, options) self.class.dependent_associations.each do |reflection| next unless (klass = get_reflection_class(reflection)).paranoid? @@ -176,7 +176,7 @@ def deleted? alias_method :destroyed?, :deleted? private - + def get_reflection_class(reflection) if reflection.macro == :belongs_to && reflection.options.include?(:polymorphic) self.send(reflection.foreign_type).constantize diff --git a/lib/acts_as_paranoid/relation.rb b/lib/acts_as_paranoid/relation.rb index 6ae97ff..a79b35f 100644 --- a/lib/acts_as_paranoid/relation.rb +++ b/lib/acts_as_paranoid/relation.rb @@ -5,7 +5,7 @@ def self.included(base) def paranoid? klass.try(:paranoid?) ? true : false end - + def paranoid_deletion_attributes { klass.paranoid_column => klass.delete_now_value } end @@ -18,7 +18,7 @@ def delete_all!(conditions = nil) orig_delete_all end end - + def delete_all(conditions = nil) if paranoid? update_all(paranoid_deletion_attributes, conditions) diff --git a/test/test_associations.rb b/test/test_associations.rb index 7fb1381..a1f1c27 100644 --- a/test/test_associations.rb +++ b/test/test_associations.rb @@ -33,7 +33,7 @@ def test_removal_with_associations end def test_belongs_to_with_deleted - paranoid_time = ParanoidTime.first + paranoid_time = ParanoidTime.first paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants.create(:name => 'dependant!') assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time @@ -46,7 +46,7 @@ def test_belongs_to_with_deleted end def test_belongs_to_polymorphic_with_deleted - paranoid_time = ParanoidTime.first + paranoid_time = ParanoidTime.first paranoid_has_many_dependant = ParanoidHasManyDependant.create!(:name => 'dependant!', :paranoid_time_polymorphic_with_deleted => paranoid_time) assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time diff --git a/test/test_core.rb b/test/test_core.rb index e5b7dd6..207d662 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -6,7 +6,7 @@ def test_paranoid? assert_raise(NoMethodError) { NotParanoid.delete_all! } assert_raise(NoMethodError) { NotParanoid.first.destroy! } assert_raise(NoMethodError) { NotParanoid.with_deleted } - assert_raise(NoMethodError) { NotParanoid.only_deleted } + assert_raise(NoMethodError) { NotParanoid.only_deleted } assert ParanoidTime.paranoid? end @@ -32,7 +32,7 @@ def test_fake_removal assert_equal 2, ParanoidTime.count assert_equal 1, ParanoidBoolean.count assert_equal 0, ParanoidString.count - assert_equal 1, ParanoidTime.only_deleted.count + assert_equal 1, ParanoidTime.only_deleted.count assert_equal 2, ParanoidBoolean.only_deleted.count assert_equal 1, ParanoidString.only_deleted.count assert_equal 3, ParanoidTime.with_deleted.count @@ -93,7 +93,7 @@ def test_recovery def setup_recursive_tests @paranoid_time_object = ParanoidTime.first - + # Create one extra ParanoidHasManyDependant record so that we can validate # the correct dependants are recovered. ParanoidTime.where('id <> ?', @paranoid_time_object.id).first.paranoid_has_many_dependants.create(:name => "should not be recovered").destroy @@ -144,7 +144,7 @@ def test_recursive_fake_removal end def test_recursive_real_removal - setup_recursive_tests + setup_recursive_tests @paranoid_time_object.destroy! @@ -180,8 +180,8 @@ def test_recursive_recovery_dependant_window @paranoid_time_object.destroy @paranoid_time_object.reload - # Stop the following from recovering: - # - ParanoidHasManyDependant and its ParanoidBelongsDependant + # Stop the following from recovering: + # - ParanoidHasManyDependant and its ParanoidBelongsDependant # - A single ParanoidBelongsDependant, but not its parent dependants = @paranoid_time_object.paranoid_has_many_dependants.with_deleted dependants.first.update_attribute(:deleted_at, 2.days.ago) @@ -197,38 +197,38 @@ def test_recursive_recovery_dependant_window assert_equal 1, NotParanoid.count assert_equal 0, HasOneNotParanoid.count end - + def test_recursive_recovery_for_belongs_to_polymorphic child_1 = ParanoidAndroid.create section_1 = ParanoidSection.create(:paranoid_thing => child_1) - + child_2 = ParanoidHuman.create(:gender => 'male') section_2 = ParanoidSection.create(:paranoid_thing => child_2) - + assert_equal section_1.paranoid_thing, child_1 assert_equal section_1.paranoid_thing.class, ParanoidAndroid assert_equal section_2.paranoid_thing, child_2 assert_equal section_2.paranoid_thing.class, ParanoidHuman - + parent = ParanoidTime.create(:name => "paranoid_parent") parent.paranoid_sections << section_1 parent.paranoid_sections << section_2 - + assert_equal 4, ParanoidTime.count assert_equal 2, ParanoidSection.count assert_equal 1, ParanoidAndroid.count assert_equal 1, ParanoidHuman.count - + parent.destroy - + assert_equal 3, ParanoidTime.count assert_equal 0, ParanoidSection.count assert_equal 0, ParanoidAndroid.count assert_equal 0, ParanoidHuman.count - + parent.reload parent.recover - + assert_equal 4, ParanoidTime.count assert_equal 2, ParanoidSection.count assert_equal 1, ParanoidAndroid.count @@ -259,25 +259,25 @@ def test_deleted? ParanoidString.first.destroy assert ParanoidString.with_deleted.first.deleted? end - - def test_paranoid_destroy_callbacks + + def test_paranoid_destroy_callbacks @paranoid_with_callback = ParanoidWithCallback.first ParanoidWithCallback.transaction do @paranoid_with_callback.destroy end - + assert @paranoid_with_callback.called_before_destroy assert @paranoid_with_callback.called_after_destroy assert @paranoid_with_callback.called_after_commit_on_destroy end - + def test_hard_destroy_callbacks @paranoid_with_callback = ParanoidWithCallback.first - + ParanoidWithCallback.transaction do @paranoid_with_callback.destroy! end - + assert @paranoid_with_callback.called_before_destroy assert @paranoid_with_callback.called_after_destroy assert @paranoid_with_callback.called_after_commit_on_destroy @@ -296,52 +296,52 @@ def test_recovery_callbacks end assert @paranoid_with_callback.called_before_recover - assert @paranoid_with_callback.called_after_recover + assert @paranoid_with_callback.called_after_recover end def test_delete_by_multiple_id_is_paranoid model_a = ParanoidBelongsDependant.create model_b = ParanoidBelongsDependant.create ParanoidBelongsDependant.delete([model_a.id, model_b.id]) - + assert_paranoid_deletion(model_a) assert_paranoid_deletion(model_b) end - + def test_destroy_by_multiple_id_is_paranoid model_a = ParanoidBelongsDependant.create model_b = ParanoidBelongsDependant.create ParanoidBelongsDependant.destroy([model_a.id, model_b.id]) - + assert_paranoid_deletion(model_a) assert_paranoid_deletion(model_b) end - + def test_delete_by_single_id_is_paranoid model = ParanoidBelongsDependant.create ParanoidBelongsDependant.delete(model.id) - + assert_paranoid_deletion(model) end - + def test_destroy_by_single_id_is_paranoid model = ParanoidBelongsDependant.create ParanoidBelongsDependant.destroy(model.id) - + assert_paranoid_deletion(model) end - + def test_instance_delete_is_paranoid model = ParanoidBelongsDependant.create model.delete - + assert_paranoid_deletion(model) end - + def test_instance_destroy_is_paranoid model = ParanoidBelongsDependant.create model.destroy - + assert_paranoid_deletion(model) end diff --git a/test/test_default_scopes.rb b/test/test_default_scopes.rb index f0344de..894ec8b 100644 --- a/test/test_default_scopes.rb +++ b/test/test_default_scopes.rb @@ -27,7 +27,7 @@ def test_fake_removal_with_multiple_default_scope assert_equal 3, ParanoidHuman.with_deleted.count assert_equal 4, ParanoidHuman.unscoped.count end - + def test_real_removal_with_multiple_default_scope # two-step ParanoidHuman.first.destroy diff --git a/test/test_helper.rb b/test/test_helper.rb index 330ed78..d1fc692 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -74,52 +74,52 @@ def setup_db t.timestamps end - + create_table :paranoid_with_callbacks do |t| t.string :name t.datetime :deleted_at - + t.timestamps end create_table :paranoid_destroy_companies do |t| t.string :name t.datetime :deleted_at - + t.timestamps end - + create_table :paranoid_delete_companies do |t| t.string :name t.datetime :deleted_at - + t.timestamps end - + create_table :paranoid_products do |t| t.integer :paranoid_destroy_company_id t.integer :paranoid_delete_company_id t.string :name t.datetime :deleted_at - + t.timestamps end - + create_table :super_paranoids do |t| t.string :type t.references :has_many_inherited_super_paranoidz t.datetime :deleted_at - + t.timestamps end - + create_table :has_many_inherited_super_paranoidzs do |t| t.references :super_paranoidz t.datetime :deleted_at - + t.timestamps end - + create_table :paranoid_many_many_parent_lefts do |t| t.string :name t.timestamps @@ -129,14 +129,14 @@ def setup_db t.string :name t.timestamps end - + create_table :paranoid_many_many_children do |t| t.integer :paranoid_many_many_parent_left_id t.integer :paranoid_many_many_parent_right_id t.datetime :deleted_at t.timestamps end - + create_table :paranoid_with_scoped_validations do |t| t.string :name t.string :category @@ -148,15 +148,15 @@ def setup_db t.string :name t.boolean :rainforest t.datetime :deleted_at - + t.timestamps end - + create_table :paranoid_trees do |t| t.integer :paranoid_forest_id t.string :name t.datetime :deleted_at - + t.timestamps end @@ -166,11 +166,11 @@ def setup_db t.timestamps end - + create_table :paranoid_androids do |t| t.datetime :deleted_at end - + create_table :paranoid_sections do |t| t.integer :paranoid_time_id t.integer :paranoid_thing_id @@ -249,31 +249,31 @@ class ParanoidHasOneDependant < ActiveRecord::Base class ParanoidWithCallback < ActiveRecord::Base acts_as_paranoid - + attr_accessor :called_before_destroy, :called_after_destroy, :called_after_commit_on_destroy attr_accessor :called_before_recover, :called_after_recover - + before_destroy :call_me_before_destroy after_destroy :call_me_after_destroy - + after_commit :call_me_after_commit_on_destroy, :on => :destroy before_recover :call_me_before_recover after_recover :call_me_after_recover - + def initialize(*attrs) @called_before_destroy = @called_after_destroy = @called_after_commit_on_destroy = false super(*attrs) end - + def call_me_before_destroy @called_before_destroy = true end - + def call_me_after_destroy @called_after_destroy = true end - + def call_me_after_commit_on_destroy @called_after_commit_on_destroy = true end @@ -381,17 +381,17 @@ def setup def teardown teardown_db end - + def assert_empty(collection) assert(collection.respond_to?(:empty?) && collection.empty?) end - + def assert_paranoid_deletion(model) row = find_row(model) assert_not_nil row, "#{model.class} entirely deleted" assert_not_nil row["deleted_at"], "Deleted at not set" end - + def assert_non_paranoid_deletion(model) row = find_row(model) assert_nil row, "#{model.class} still exists" diff --git a/test/test_inheritance.rb b/test/test_inheritance.rb index bad4dc0..d4a3f57 100644 --- a/test/test_inheritance.rb +++ b/test/test_inheritance.rb @@ -7,9 +7,8 @@ def test_destroy_dependents_with_inheritance has_many_inherited_super_paranoidz.super_paranoidz.create assert_nothing_raised(NoMethodError) { has_many_inherited_super_paranoidz.destroy } end - + def test_class_instance_variables_are_inherited assert_nothing_raised(ActiveRecord::StatementInvalid) { InheritedParanoid.paranoid_column } end end - diff --git a/test/test_observers.rb b/test/test_observers.rb index f67b3fb..6a60efe 100644 --- a/test/test_observers.rb +++ b/test/test_observers.rb @@ -7,7 +7,7 @@ def test_called_observer_methods assert_nil ParanoidObserver.instance.called_before_recover assert_nil ParanoidObserver.instance.called_after_recover - + ParanoidWithCallback.find(@subject.id).recover assert_equal @subject, ParanoidObserver.instance.called_before_recover diff --git a/test/test_relations.rb b/test/test_relations.rb index db28164..ee00e51 100644 --- a/test/test_relations.rb +++ b/test/test_relations.rb @@ -2,7 +2,7 @@ class RelationsTest < ParanoidBaseTest def setup - setup_db + setup_db @paranoid_forest_1 = ParanoidForest.create! :name => "ParanoidForest #1" @paranoid_forest_2 = ParanoidForest.create! :name => "ParanoidForest #2", :rainforest => true @@ -72,7 +72,7 @@ def test_associations_filtered_by_only_deleted assert_equal 2, @paranoid_forest_1.paranoid_trees.only_deleted.count assert_equal 3, ParanoidTree.only_deleted.count end - + def test_fake_removal_through_relation # destroy: through a relation. ParanoidForest.rainforest.destroy(@paranoid_forest_3) @@ -85,14 +85,14 @@ def test_fake_removal_through_relation assert_equal 0, @paranoid_forest_2.paranoid_trees(true).count assert_equal 2, @paranoid_forest_2.paranoid_trees(true).with_deleted.count end - + def test_real_removal_through_relation # destroy!: aliased to delete ParanoidForest.rainforest.destroy!(@paranoid_forest_3) assert_equal 1, ParanoidForest.rainforest.count assert_equal 1, ParanoidForest.rainforest.with_deleted.count assert_equal 0, ParanoidForest.rainforest.only_deleted.count - + # destroy: two-step through a relation paranoid_tree = @paranoid_forest_1.paranoid_trees.first @paranoid_forest_1.paranoid_trees.order(:id).destroy(paranoid_tree) diff --git a/test/test_validations.rb b/test/test_validations.rb index 1208ad8..9f05d3d 100644 --- a/test/test_validations.rb +++ b/test/test_validations.rb @@ -23,19 +23,19 @@ def test_should_validate_without_deleted def test_models_with_scoped_validations_can_be_multiply_deleted model_a = ParanoidWithScopedValidation.create(:name => "Model A", :category => "Category A") model_b = ParanoidWithScopedValidation.create(:name => "Model B", :category => "Category B") - + ParanoidWithScopedValidation.delete([model_a.id, model_b.id]) - + assert_paranoid_deletion(model_a) assert_paranoid_deletion(model_b) end - + def test_models_with_scoped_validations_can_be_multiply_destroyed model_a = ParanoidWithScopedValidation.create(:name => "Model A", :category => "Category A") model_b = ParanoidWithScopedValidation.create(:name => "Model B", :category => "Category B") - + ParanoidWithScopedValidation.destroy([model_a.id, model_b.id]) - + assert_paranoid_deletion(model_a) assert_paranoid_deletion(model_b) end From f4fc7ba9f6e7841b0e3841c0eb5e6092741883cb Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 21:26:51 +0100 Subject: [PATCH 010/105] Modernized the gem, and a few other tweaks. Now it looks like what a gem generated with `bundle gem` would look like. Also: - Change requirements back to ActiveRecord 3.1, seen as the gem is not ready for prime time with Rails 4; - Silence tests; - Indicate which license this gem has. --- Gemfile | 17 ++++++---------- Rakefile | 27 +++---------------------- acts_as_paranoid.gemspec | 36 +++++++++++++++++++-------------- lib/acts_as_paranoid.rb | 4 ---- lib/acts_as_paranoid/version.rb | 3 +++ test/test_helper.rb | 21 ++++++++++--------- 6 files changed, 44 insertions(+), 64 deletions(-) create mode 100644 lib/acts_as_paranoid/version.rb diff --git a/Gemfile b/Gemfile index e970d10..cc071a4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,15 +1,10 @@ -source "http://rubygems.org" - -gem "activerecord", "~>3.2" +source "https://rubygems.org" # Development dependencies -gem "rake" -gem "activesupport", "~>3.2" - -platforms :ruby do - gem "sqlite3" -end +group :development do + gem "activerecord", ">= 3.0", "<= 4.0", :require => "active_record" + gem "activesupport", ">= 3.0", "<= 4.0", :require => "active_support" -platforms :jruby do - gem "activerecord-jdbcsqlite3-adapter" + gem "sqlite3", :platforms => [:ruby] + gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] end diff --git a/Rakefile b/Rakefile index 179ffd7..40472ed 100755 --- a/Rakefile +++ b/Rakefile @@ -1,9 +1,5 @@ -begin - require "bundler" - Bundler.setup -rescue LoadError - $stderr.puts "You need to have Bundler installed to be able build this gem." -end +require "bundler/gem_tasks" + require "rake/testtask" require "rdoc/task" @@ -14,13 +10,8 @@ task :default => :test desc 'Test the acts_as_paranoid plugin.' Rake::TestTask.new(:test) do |t| - t.libs << 'lib' t.libs << 'test' - - test_files = FileList['test/**/test_*.rb'] - test_files.exclude('test/test_helper.rb') - t.test_files = test_files - + t.pattern = 'test/test_*.rb' t.verbose = true end @@ -33,18 +24,6 @@ Rake::RDocTask.new(:rdoc) do |rdoc| rdoc.rdoc_files.include('lib/**/*.rb') end -desc "Validate the gemspec" -task :gemspec do - gemspec.validate -end - -desc "Build gem locally" -task :build => :gemspec do - system "gem build #{gemspec.name}.gemspec" - FileUtils.mkdir_p "pkg" - FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", "pkg" -end - desc "Install gem locally" task :install => :build do system "gem install pkg/#{gemspec.name}-#{gemspec.version}" diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 1502885..d4f1794 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -1,20 +1,26 @@ -Gem::Specification.new do |s| - s.name = "acts_as_paranoid" - s.version = "0.5.0" - s.platform = Gem::Platform::RUBY - s.authors = ["Goncalo Silva", "Charles G.", "Rick Olson"] - s.email = ["goncalossilva@gmail.com"] - s.homepage = "https://github.com/goncalossilva/rails3_acts_as_paranoid" - s.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." - s.description = "Active Record plugin which allows you to hide and restore records without actually deleting them. Check its GitHub page for more in-depth information." - s.rubyforge_project = s.name +# coding: utf-8 +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'acts_as_paranoid/version' - s.required_rubygems_version = ">= 1.3.6" +Gem::Specification.new do |spec| + spec.name = "acts_as_paranoid" + spec.version = ActsAsParanoid::VERSION + spec.authors = ["Goncalo Silva", "Charles G.", "Rick Olson"] + spec.email = ["goncalossilva@gmail.com"] + spec.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." + spec.description = "Active Record plugin which allows you to hide and restore records without actually deleting them. Check its GitHub page for more in-depth information." + spec.homepage = "https://github.com/goncalossilva/rails3_acts_as_paranoid" + spec.license = "MIT" - s.add_dependency "activerecord", ">= 4.0.0" + spec.files = Dir["{lib}/**/*.rb", "LICENSE", "*.md"] + spec.test_files = Dir["test/*.rb"] + spec.require_paths = ["lib"] - s.add_development_dependency "minitest" - s.add_development_dependency 'rake', ['>= 0'] + spec.required_rubygems_version = ">= 1.3.6" - s.files = Dir["{lib}/**/*.rb", "LICENSE", "*.markdown"] + spec.add_dependency "activerecord", ">= 3.1", "< 4.0" + + spec.add_development_dependency "bundler", "~> 1.5" + spec.add_development_dependency "rake" end diff --git a/lib/acts_as_paranoid.rb b/lib/acts_as_paranoid.rb index ef12798..11bf5e4 100644 --- a/lib/acts_as_paranoid.rb +++ b/lib/acts_as_paranoid.rb @@ -1,12 +1,8 @@ -require 'active_record/base' -require 'active_record/relation' -require 'active_record/callbacks' require 'acts_as_paranoid/core' require 'acts_as_paranoid/associations' require 'acts_as_paranoid/validations' require 'acts_as_paranoid/relation' - module ActsAsParanoid def paranoid? diff --git a/lib/acts_as_paranoid/version.rb b/lib/acts_as_paranoid/version.rb new file mode 100644 index 0000000..dd7c2d6 --- /dev/null +++ b/lib/acts_as_paranoid/version.rb @@ -0,0 +1,3 @@ +module ActsAsParanoid + VERSION = "0.5.0" +end diff --git a/test/test_helper.rb b/test/test_helper.rb index d1fc692..0c7e828 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,16 +1,17 @@ -require 'rubygems' -require 'test/unit' -require 'active_support' -require 'active_record' -require 'active_model' - -$:.unshift "#{File.dirname(__FILE__)}/../" -$:.unshift "#{File.dirname(__FILE__)}/../lib/" -$:.unshift "#{File.dirname(__FILE__)}/../lib/validations" +require 'bundler' +begin + Bundler.require(:default, :development) +rescue Bundler::BundlerError => e + $stderr.puts e.message + $stderr.puts "Run `bundle install` to install missing gems" + exit e.status_code +end -require 'init' +require 'acts_as_paranoid' +require 'minitest/autorun' ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") +ActiveRecord::Schema.verbose = false def setup_db ActiveRecord::Schema.define(:version => 1) do From 5a47cdf87c9eda7851bf6dbf677f8361a1ea9b77 Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 21:59:21 +0100 Subject: [PATCH 011/105] Support AR from 3.0 onwards. --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index d4f1794..1192321 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |spec| spec.required_rubygems_version = ">= 1.3.6" - spec.add_dependency "activerecord", ">= 3.1", "< 4.0" + spec.add_dependency "activerecord", ">= 3.0", "< 4.0" spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" From 86ecbcd6316f793b0148e35c5e1b7bcbc12839d2 Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 23:09:25 +0100 Subject: [PATCH 012/105] Added gemfiles to test AR 3.1 and 3.2 --- gemfiles/active_record_31.gemfile | 12 ++++++++++++ gemfiles/active_record_32.gemfile | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 gemfiles/active_record_31.gemfile create mode 100644 gemfiles/active_record_32.gemfile diff --git a/gemfiles/active_record_31.gemfile b/gemfiles/active_record_31.gemfile new file mode 100644 index 0000000..d7cea84 --- /dev/null +++ b/gemfiles/active_record_31.gemfile @@ -0,0 +1,12 @@ +source "https://rubygems.org" + +# Development dependencies +group :development do + gem "activerecord", "~> 3.1.0", :require => "active_record" + gem "activesupport", "~> 3.1.0", :require => "active_support" + + gem "sqlite3", :platforms => [:ruby] + gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] +end + +gemspec :path => '../' diff --git a/gemfiles/active_record_32.gemfile b/gemfiles/active_record_32.gemfile new file mode 100644 index 0000000..f791ec2 --- /dev/null +++ b/gemfiles/active_record_32.gemfile @@ -0,0 +1,12 @@ +source "https://rubygems.org" + +# Development dependencies +group :development do + gem "activerecord", "~> 3.2.0", :require => "active_record" + gem "activesupport", "~> 3.2.0", :require => "active_support" + + gem "sqlite3", :platforms => [:ruby] + gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] +end + +gemspec :path => '../' From d5a831f8685fd4479072afb42c6e5326eec88e81 Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 23:09:55 +0100 Subject: [PATCH 013/105] Make Travis test only the versions that we actually support --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 611987a..912c319 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,8 @@ rvm: - jruby - rbx gemfile: - - gemfiles/active_record_40.gemfile - - gemfiles/active_record_41.gemfile - - gemfiles/active_record_edge.gemfile + - gemfiles/active_record_31.gemfile + - gemfiles/active_record_32.gemfile matrix: allow_failures: - rvm: rbx From 95ecde76e0cb21361e2a7640853e1aaaaaaab2fe Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 23:27:46 +0100 Subject: [PATCH 014/105] Lock sqlite3 version so tests run with rbx --- README.markdown => README.md | 0 gemfiles/active_record_31.gemfile | 2 +- gemfiles/active_record_32.gemfile | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename README.markdown => README.md (100%) diff --git a/README.markdown b/README.md similarity index 100% rename from README.markdown rename to README.md diff --git a/gemfiles/active_record_31.gemfile b/gemfiles/active_record_31.gemfile index d7cea84..bf18c32 100644 --- a/gemfiles/active_record_31.gemfile +++ b/gemfiles/active_record_31.gemfile @@ -5,7 +5,7 @@ group :development do gem "activerecord", "~> 3.1.0", :require => "active_record" gem "activesupport", "~> 3.1.0", :require => "active_support" - gem "sqlite3", :platforms => [:ruby] + gem "sqlite3", "1.3.8", :platforms => [:ruby] gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] end diff --git a/gemfiles/active_record_32.gemfile b/gemfiles/active_record_32.gemfile index f791ec2..4454e37 100644 --- a/gemfiles/active_record_32.gemfile +++ b/gemfiles/active_record_32.gemfile @@ -5,7 +5,7 @@ group :development do gem "activerecord", "~> 3.2.0", :require => "active_record" gem "activesupport", "~> 3.2.0", :require => "active_support" - gem "sqlite3", :platforms => [:ruby] + gem "sqlite3", "1.3.8", :platforms => [:ruby] gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] end From e2ad638f306b0c7317a84636f10fb2d6979220f8 Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 23:34:44 +0100 Subject: [PATCH 015/105] Silence more deprecations --- test/test_helper.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_helper.rb b/test/test_helper.rb index 0c7e828..41cf228 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -10,6 +10,9 @@ require 'acts_as_paranoid' require 'minitest/autorun' +# Silence deprecation halfway through the test +I18n.enforce_available_locales = true + ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") ActiveRecord::Schema.verbose = false From c36e3edef9db749e9a21141a383756b54f0d9671 Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 23:37:54 +0100 Subject: [PATCH 016/105] Documentation improvements - Add build status badge - Mention that the gem also works for Rails 3.1 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bf90140..cd923db 100755 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # ActsAsParanoid +[![Build Status](https://travis-ci.org/zzak/acts_as_paranoid.png?branch=master)](https://travis-ci.org/zzak/acts_as_paranoid) + A simple plugin which hides records instead of deleting them, being able to recover them. -**This branch targets Rails 3.2.** If you're working with another version, switch to the corresponding branch. +**This branch targets Rails 3.1 and 3.2.** If you're working with another version, switch to the corresponding branch. ## Credits From 1bb293a10a8a8910e472e19c9fe1784887f1190f Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Fri, 7 Mar 2014 23:48:12 +0100 Subject: [PATCH 017/105] Move the AR dependency back to 3.1 --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 1192321..d4f1794 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |spec| spec.required_rubygems_version = ">= 1.3.6" - spec.add_dependency "activerecord", ">= 3.0", "< 4.0" + spec.add_dependency "activerecord", ">= 3.1", "< 4.0" spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" From 48ff3128f583c583370c1ff9c9c89b0b813d6baa Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Sat, 5 Apr 2014 16:33:53 +0200 Subject: [PATCH 018/105] Add Zachary to the authors and change the gem homepage. --- acts_as_paranoid.gemspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index d4f1794..b614253 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -6,11 +6,11 @@ require 'acts_as_paranoid/version' Gem::Specification.new do |spec| spec.name = "acts_as_paranoid" spec.version = ActsAsParanoid::VERSION - spec.authors = ["Goncalo Silva", "Charles G.", "Rick Olson"] - spec.email = ["goncalossilva@gmail.com"] + spec.authors = ["Zachary Scott" "Goncalo Silva", "Charles G.", "Rick Olson"] + spec.email = ["e@zzak.io"] spec.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." spec.description = "Active Record plugin which allows you to hide and restore records without actually deleting them. Check its GitHub page for more in-depth information." - spec.homepage = "https://github.com/goncalossilva/rails3_acts_as_paranoid" + spec.homepage = "https://github.com/zzak/acts_as_paranoid" spec.license = "MIT" spec.files = Dir["{lib}/**/*.rb", "LICENSE", "*.md"] From 5a23726768a20a9b5cf822069106bf4b7318b68f Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:32:55 -0700 Subject: [PATCH 019/105] Test Ruby 2.1.x [ci skip] --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 912c319..179f2ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: ruby rvm: - 1.9.3 - 2.0.0 - - 2.1.0 + - 2.1 - jruby - rbx gemfile: From 879c66e0c0f5af8d26093303dbc937beed120082 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:36:49 -0700 Subject: [PATCH 020/105] Delete duplicate description content --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index b614253..ecfba8f 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |spec| spec.authors = ["Zachary Scott" "Goncalo Silva", "Charles G.", "Rick Olson"] spec.email = ["e@zzak.io"] spec.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." - spec.description = "Active Record plugin which allows you to hide and restore records without actually deleting them. Check its GitHub page for more in-depth information." + spec.description = "Check the home page for more in-depth information." spec.homepage = "https://github.com/zzak/acts_as_paranoid" spec.license = "MIT" From e7da594310d07895e63ab18e4eafba096409c305 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:37:10 -0700 Subject: [PATCH 021/105] Use original 0.4.x ActiveRecord dependency, we shouldn't change this between patch level releases. --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index ecfba8f..e2e7820 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |spec| spec.required_rubygems_version = ">= 1.3.6" - spec.add_dependency "activerecord", ">= 3.1", "< 4.0" + spec.add_dependency "activerecord", "~> 3.2" spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" From b8ebaef871ee097667e54cfb8624a43f97653d2d Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:38:15 -0700 Subject: [PATCH 022/105] Preparing 0.4.x patch level release first --- lib/acts_as_paranoid/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/version.rb b/lib/acts_as_paranoid/version.rb index dd7c2d6..309865e 100644 --- a/lib/acts_as_paranoid/version.rb +++ b/lib/acts_as_paranoid/version.rb @@ -1,3 +1,3 @@ module ActsAsParanoid - VERSION = "0.5.0" + VERSION = "0.4.3" end From 2e9fd780a4eccbc7b560c9f342b4ad28b1c8b538 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:49:12 -0700 Subject: [PATCH 023/105] For this release we don't need AR 4+ gemfiles --- gemfiles/active_record_40.gemfile | 13 ------------- gemfiles/active_record_41.gemfile | 15 --------------- gemfiles/active_record_edge.gemfile | 15 --------------- 3 files changed, 43 deletions(-) delete mode 100644 gemfiles/active_record_40.gemfile delete mode 100644 gemfiles/active_record_41.gemfile delete mode 100644 gemfiles/active_record_edge.gemfile diff --git a/gemfiles/active_record_40.gemfile b/gemfiles/active_record_40.gemfile deleted file mode 100644 index 40183ef..0000000 --- a/gemfiles/active_record_40.gemfile +++ /dev/null @@ -1,13 +0,0 @@ -source 'https://rubygems.org' - -gem 'activerecord', '~> 4.0.0', :require => 'active_record' -gem 'activesupport', '~> 4.0.0', :require => 'active_record' - -platforms :ruby, :rbx do - gem 'sqlite3' -end -platforms :jruby do - gem 'activerecord-jdbcsqlite3-adapter' -end - -gemspec :path => '../' diff --git a/gemfiles/active_record_41.gemfile b/gemfiles/active_record_41.gemfile deleted file mode 100644 index 2908b56..0000000 --- a/gemfiles/active_record_41.gemfile +++ /dev/null @@ -1,15 +0,0 @@ -source 'https://rubygems.org' - -git 'git://github.com/rails/rails.git', :branch => '4-1-stable' do - gem 'activerecord', :require => 'active_record' - gem 'activesupport', :require => 'active_record' -end - -platforms :ruby, :rbx do - gem 'sqlite3' -end -platforms :jruby do - gem 'activerecord-jdbcsqlite3-adapter' -end - -gemspec :path => '../' diff --git a/gemfiles/active_record_edge.gemfile b/gemfiles/active_record_edge.gemfile deleted file mode 100644 index a8c30ab..0000000 --- a/gemfiles/active_record_edge.gemfile +++ /dev/null @@ -1,15 +0,0 @@ -source 'https://rubygems.org' - -git 'git://github.com/rails/rails.git' do - gem 'activerecord', :require => 'active_record' - gem 'activesupport', :require => 'active_record' -end - -platforms :ruby, :rbx do - gem 'sqlite3' -end -platforms :jruby do - gem 'activerecord-jdbcsqlite3-adapter' -end - -gemspec :path => '../' From e9cf44b73a24dc07c3bed6aa3875e986b5e20fbc Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:56:47 -0700 Subject: [PATCH 024/105] Use pessimistic dependency requirement --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index cc071a4..5df3784 100644 --- a/Gemfile +++ b/Gemfile @@ -2,8 +2,8 @@ source "https://rubygems.org" # Development dependencies group :development do - gem "activerecord", ">= 3.0", "<= 4.0", :require => "active_record" - gem "activesupport", ">= 3.0", "<= 4.0", :require => "active_support" + gem "activerecord", "~> 3.2", :require => "active_record" + gem "activesupport", "~> 3.2", :require => "active_support" gem "sqlite3", :platforms => [:ruby] gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] From 7fb0b5c4a0b77270c8409dea64d7462dea609da6 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:57:16 -0700 Subject: [PATCH 025/105] Use gemspec for remaining dependencies --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 5df3784..3c07fbb 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,5 @@ source "https://rubygems.org" +gemspec # Development dependencies group :development do From fa21bfa9766662d8bab1835d21f8c288a9a71149 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:57:53 -0700 Subject: [PATCH 026/105] Fix typo in gemspec authors --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index e2e7820..cd17672 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -6,7 +6,7 @@ require 'acts_as_paranoid/version' Gem::Specification.new do |spec| spec.name = "acts_as_paranoid" spec.version = ActsAsParanoid::VERSION - spec.authors = ["Zachary Scott" "Goncalo Silva", "Charles G.", "Rick Olson"] + spec.authors = ["Zachary Scott", "Goncalo Silva", "Charles G.", "Rick Olson"] spec.email = ["e@zzak.io"] spec.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." spec.description = "Check the home page for more in-depth information." From 0a6613217b2e1a0da0240db3c00ce57b53a40c73 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 10:58:46 -0700 Subject: [PATCH 027/105] =?UTF-8?q?Add=20Andr=C3=A9=20Medeiros=20for=20his?= =?UTF-8?q?=20help!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index cd17672..536697a 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -6,7 +6,7 @@ require 'acts_as_paranoid/version' Gem::Specification.new do |spec| spec.name = "acts_as_paranoid" spec.version = ActsAsParanoid::VERSION - spec.authors = ["Zachary Scott", "Goncalo Silva", "Charles G.", "Rick Olson"] + spec.authors = ["Zachary Scott", "André Medeiros", "Goncalo Silva", "Charles G.", "Rick Olson"] spec.email = ["e@zzak.io"] spec.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." spec.description = "Check the home page for more in-depth information." From 5a1bafd4d4b27292ffc223c667639cf3c6731772 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 11:09:46 -0700 Subject: [PATCH 028/105] Enable 1.8.7 for Rails 3.x --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 179f2ec..62715f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: ruby rvm: + - 1.8.7 - 1.9.3 - 2.0.0 - 2.1 From ee967855a11ec732f1cb4c7dc0049bf95a8d124b Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 11:10:49 -0700 Subject: [PATCH 029/105] Allow testing of AR 3.0.0 since this patch level supports all Rails 3.x versions --- .travis.yml | 1 + gemfiles/active_record_30.gemfile | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 gemfiles/active_record_30.gemfile diff --git a/.travis.yml b/.travis.yml index 62715f0..5abd4b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ rvm: - jruby - rbx gemfile: + - gemfiles/active_record_30.gemfile - gemfiles/active_record_31.gemfile - gemfiles/active_record_32.gemfile matrix: diff --git a/gemfiles/active_record_30.gemfile b/gemfiles/active_record_30.gemfile new file mode 100644 index 0000000..d894d5e --- /dev/null +++ b/gemfiles/active_record_30.gemfile @@ -0,0 +1,12 @@ +source "https://rubygems.org" + +# Development dependencies +group :development do + gem "activerecord", "~> 3.0.0", :require => "active_record" + gem "activesupport", "~> 3.0.0", :require => "active_support" + + gem "sqlite3", "1.3.8", :platforms => [:ruby] + gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] +end + +gemspec :path => '../' From 6714ab99d1f0b39c21a4913a10ef3634a8e99ecd Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 11:36:02 -0700 Subject: [PATCH 030/105] Revert "Allow testing of AR 3.0.0 since this patch level supports all Rails 3.x versions" This reverts commit ee967855a11ec732f1cb4c7dc0049bf95a8d124b. --- .travis.yml | 1 - gemfiles/active_record_30.gemfile | 12 ------------ 2 files changed, 13 deletions(-) delete mode 100644 gemfiles/active_record_30.gemfile diff --git a/.travis.yml b/.travis.yml index 5abd4b4..62715f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ rvm: - jruby - rbx gemfile: - - gemfiles/active_record_30.gemfile - gemfiles/active_record_31.gemfile - gemfiles/active_record_32.gemfile matrix: diff --git a/gemfiles/active_record_30.gemfile b/gemfiles/active_record_30.gemfile deleted file mode 100644 index d894d5e..0000000 --- a/gemfiles/active_record_30.gemfile +++ /dev/null @@ -1,12 +0,0 @@ -source "https://rubygems.org" - -# Development dependencies -group :development do - gem "activerecord", "~> 3.0.0", :require => "active_record" - gem "activesupport", "~> 3.0.0", :require => "active_support" - - gem "sqlite3", "1.3.8", :platforms => [:ruby] - gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] -end - -gemspec :path => '../' From f13cc2f1d42e36864f7c2ff940e97f80b54827a5 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 11:37:26 -0700 Subject: [PATCH 031/105] Correction, this patch level release will only support Rails 3.2.x --- .travis.yml | 1 - README.md | 2 +- gemfiles/active_record_31.gemfile | 12 ------------ 3 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 gemfiles/active_record_31.gemfile diff --git a/.travis.yml b/.travis.yml index 62715f0..b34b484 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ rvm: - jruby - rbx gemfile: - - gemfiles/active_record_31.gemfile - gemfiles/active_record_32.gemfile matrix: allow_failures: diff --git a/README.md b/README.md index cd923db..f550f8a 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A simple plugin which hides records instead of deleting them, being able to recover them. -**This branch targets Rails 3.1 and 3.2.** If you're working with another version, switch to the corresponding branch. +**This branch targets Rails 3.2.** If you're working with another version, switch to the corresponding branch. ## Credits diff --git a/gemfiles/active_record_31.gemfile b/gemfiles/active_record_31.gemfile deleted file mode 100644 index bf18c32..0000000 --- a/gemfiles/active_record_31.gemfile +++ /dev/null @@ -1,12 +0,0 @@ -source "https://rubygems.org" - -# Development dependencies -group :development do - gem "activerecord", "~> 3.1.0", :require => "active_record" - gem "activesupport", "~> 3.1.0", :require => "active_support" - - gem "sqlite3", "1.3.8", :platforms => [:ruby] - gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] -end - -gemspec :path => '../' From 546267ed13f3bded4741165e99e3ed76ad0d020f Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 11:38:42 -0700 Subject: [PATCH 032/105] Markdown syntax --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f550f8a..ff69d71 100755 --- a/README.md +++ b/README.md @@ -224,15 +224,15 @@ This gem supports the most recent versions of Rails and Ruby. For Rails 3.2 check the README at the [rails3.2](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.2) branch and add this to your Gemfile: - gem "acts_as_paranoid", "~>0.4.0" + gem "acts_as_paranoid", "~> 0.4.0" For Rails 3.1 check the README at the [rails3.1](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.1) branch and add this to your Gemfile: - gem "rails3_acts_as_paranoid", "~>0.1.4" + gem "rails3_acts_as_paranoid", "~>0.1.4" For Rails 3.0 check the README at the [rails3.0](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.0) branch and add this to your Gemfile: - gem "rails3_acts_as_paranoid", "~>0.0.9" + gem "rails3_acts_as_paranoid", "~>0.0.9" ## Ruby From b1b61c112a243953c4a01a3241e9342fc64b2eb5 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 11:38:55 -0700 Subject: [PATCH 033/105] Rails 3.2 still supported Ruby 1.8, so we should do our best. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ff69d71..200423a 100755 --- a/README.md +++ b/README.md @@ -237,7 +237,7 @@ For Rails 3.0 check the README at the [rails3.0](https://github.com/goncalossilv ## Ruby -This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode). It *might* work fine in 1.8, but it's not officially supported. +This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode). # Acknowledgements From 7b9b0d7e79e4d508930614d75bf96b7edfd996f6 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 11:56:18 -0700 Subject: [PATCH 034/105] Make sure we use latest sqlite3 1.3.x when testing --- gemfiles/active_record_32.gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gemfiles/active_record_32.gemfile b/gemfiles/active_record_32.gemfile index 4454e37..d998ad1 100644 --- a/gemfiles/active_record_32.gemfile +++ b/gemfiles/active_record_32.gemfile @@ -5,7 +5,7 @@ group :development do gem "activerecord", "~> 3.2.0", :require => "active_record" gem "activesupport", "~> 3.2.0", :require => "active_support" - gem "sqlite3", "1.3.8", :platforms => [:ruby] + gem "sqlite3", "~> 1.3.9", :platforms => [:ruby] gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] end From 61b26a5cb92bde3e0248dd35020ffd7a7d3cc3e1 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 14:14:19 -0700 Subject: [PATCH 035/105] Move gemspec after platform dependencies --- Gemfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3c07fbb..9f25015 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,4 @@ source "https://rubygems.org" -gemspec # Development dependencies group :development do @@ -9,3 +8,5 @@ group :development do gem "sqlite3", :platforms => [:ruby] gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] end + +gemspec From a944af80ec85513998f5ae7a8db97948fb5bf6fa Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 14:20:58 -0700 Subject: [PATCH 036/105] Move Credits below Acknowledgements [ci skip] --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 200423a..decde1c 100755 --- a/README.md +++ b/README.md @@ -6,12 +6,6 @@ A simple plugin which hides records instead of deleting them, being able to reco **This branch targets Rails 3.2.** If you're working with another version, switch to the corresponding branch. -## Credits - -This plugin was inspired by [acts_as_paranoid](http://github.com/technoweenie/acts_as_paranoid) and [acts_as_active](http://github.com/fernandoluizao/acts_as_active). - -While porting it to Rails 3, I decided to apply the ideas behind those plugins to an unified solution while removing a **lot** of the complexity found in them. I eventually ended up writing a new plugin from scratch. - ## Usage You can enable ActsAsParanoid like this: @@ -239,6 +233,7 @@ For Rails 3.0 check the README at the [rails3.0](https://github.com/goncalossilv This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode). + # Acknowledgements * To [cheerfulstoic](https://github.com/cheerfulstoic) for adding recursive recovery @@ -249,4 +244,8 @@ This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode). * To [Craig Walker](https://github.com/softcraft-development) for Rails 3.1 support and fixing various pending issues * To [Charles G.](https://github.com/chuckg) for Rails 3.2 support and for making a desperately needed global code refactoring -Copyright © 2010 Gonçalo Silva, released under the MIT license +## Credits + +This plugin was inspired by [acts_as_paranoid](http://github.com/technoweenie/acts_as_paranoid) and [acts_as_active](http://github.com/fernandoluizao/acts_as_active). + +While porting it to Rails 3, I decided to apply the ideas behind those plugins to an unified solution while removing a **lot** of the complexity found in them. I eventually ended up writing a new plugin from scratch. From 2fcc4c6a9fb2225ace2b7e59039348c49fccd7ba Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 14:21:16 -0700 Subject: [PATCH 037/105] Update Copyright notice [ci skip] --- LICENSE | 2 +- README.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index e7c30a7..19d12a2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2010 Gonçalo Silva +Copyright (c) 2014 Zachary Scott, Gonçalo Silva, Rick Olson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.md b/README.md index decde1c..9e3a186 100755 --- a/README.md +++ b/README.md @@ -249,3 +249,6 @@ This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode). This plugin was inspired by [acts_as_paranoid](http://github.com/technoweenie/acts_as_paranoid) and [acts_as_active](http://github.com/fernandoluizao/acts_as_active). While porting it to Rails 3, I decided to apply the ideas behind those plugins to an unified solution while removing a **lot** of the complexity found in them. I eventually ended up writing a new plugin from scratch. + + +Copyright © 2014 Zachary Scott, Gonçalo Silva, Rick Olson, released under the MIT license From 990a9c7ff3c39c85237bb1560cd8c742cc61cac7 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 14:27:34 -0700 Subject: [PATCH 038/105] Add rdoc as development dependency to let Ruby 1.8 tests run --- acts_as_paranoid.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 536697a..05752dc 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -23,4 +23,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" + spec.add_development_dependency "rdoc" end From 17cf61abf34bdc607395ed7a8f8bcf5f12f8a21f Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 14:40:14 -0700 Subject: [PATCH 039/105] Add minitest as development dependency to let tests run on Ruby 1.8 --- acts_as_paranoid.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 05752dc..a44a119 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -24,4 +24,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" spec.add_development_dependency "rdoc" + spec.add_development_dependency "minitest", "~> 4.0" end From 37725d84c54e04a05d3fe83b34d292715114a259 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 14:51:19 -0700 Subject: [PATCH 040/105] Remove ./gemfiles since we only test one version of Rails --- .travis.yml | 2 -- gemfiles/active_record_32.gemfile | 12 ------------ 2 files changed, 14 deletions(-) delete mode 100644 gemfiles/active_record_32.gemfile diff --git a/.travis.yml b/.travis.yml index b34b484..68410fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,6 @@ rvm: - 2.1 - jruby - rbx -gemfile: - - gemfiles/active_record_32.gemfile matrix: allow_failures: - rvm: rbx diff --git a/gemfiles/active_record_32.gemfile b/gemfiles/active_record_32.gemfile deleted file mode 100644 index d998ad1..0000000 --- a/gemfiles/active_record_32.gemfile +++ /dev/null @@ -1,12 +0,0 @@ -source "https://rubygems.org" - -# Development dependencies -group :development do - gem "activerecord", "~> 3.2.0", :require => "active_record" - gem "activesupport", "~> 3.2.0", :require => "active_support" - - gem "sqlite3", "~> 1.3.9", :platforms => [:ruby] - gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] -end - -gemspec :path => '../' From 5e6bc34ce6583a6997853908fc5afbc5e5665853 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 14:59:53 -0700 Subject: [PATCH 041/105] Mark as pre-release --- lib/acts_as_paranoid/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/version.rb b/lib/acts_as_paranoid/version.rb index 309865e..42b729b 100644 --- a/lib/acts_as_paranoid/version.rb +++ b/lib/acts_as_paranoid/version.rb @@ -1,3 +1,3 @@ module ActsAsParanoid - VERSION = "0.4.3" + VERSION = "0.4.3.pre" end From fbcbdd4ac6fcc9d2f7e0a337b5587f425bd3530a Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 15:11:18 -0700 Subject: [PATCH 042/105] Master is now 0.5.x --- lib/acts_as_paranoid/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/version.rb b/lib/acts_as_paranoid/version.rb index 42b729b..bdf0c3a 100644 --- a/lib/acts_as_paranoid/version.rb +++ b/lib/acts_as_paranoid/version.rb @@ -1,3 +1,3 @@ module ActsAsParanoid - VERSION = "0.4.3.pre" + VERSION = "0.5.0.beta" end From b583c3c1f9c9ad764cae8f45b8997e4e98ff4f09 Mon Sep 17 00:00:00 2001 From: Jim Ray Date: Tue, 27 Aug 2013 21:00:25 -0600 Subject: [PATCH 043/105] Update README.markdown --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9e3a186..dd91613 100755 --- a/README.md +++ b/README.md @@ -190,6 +190,9 @@ class ParanoiacChild < ActiveRecord::Base belongs_to :parent belongs_to :parent_including_deleted, :class_name => "Parent", :with_deleted => true # You cannot name association *_with_deleted + + # You may need to provide a foreign_key like this + belongs_to :parent_including_deleted, :class_name => "Parent", foreign_key => 'parent_id', :with_deleted => true end parent = Parent.first From 17617a4291cae200a981b69d5304ee122847c030 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 12 May 2014 15:35:58 -0700 Subject: [PATCH 044/105] Merge andremedeiros/acts_as_paranoid@f77770e manually --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dd91613..eda14eb 100755 --- a/README.md +++ b/README.md @@ -183,14 +183,13 @@ Associations are also supported. From the simplest behaviors you'd expect to mor ```ruby class Parent < ActiveRecord::Base - has_many :children, :class_name => "ParanoiacChild" + has_many :children, :class_name => "ParanoiacChild" end class ParanoiacChild < ActiveRecord::Base - belongs_to :parent - belongs_to :parent_including_deleted, :class_name => "Parent", :with_deleted => true - # You cannot name association *_with_deleted - + acts_as_paranoid + belongs_to :parent + # You may need to provide a foreign_key like this belongs_to :parent_including_deleted, :class_name => "Parent", foreign_key => 'parent_id', :with_deleted => true end From d2748d634db0d825ddb0af636d73d59daa8ae2d6 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sun, 10 Aug 2014 21:20:34 -0700 Subject: [PATCH 045/105] Remove init.rb --- init.rb | 1 - 1 file changed, 1 deletion(-) delete mode 100755 init.rb diff --git a/init.rb b/init.rb deleted file mode 100755 index d0833ab..0000000 --- a/init.rb +++ /dev/null @@ -1 +0,0 @@ -require 'acts_as_paranoid' From c1e40045178d4849ee0975cadd9f3062efe94c96 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sun, 10 Aug 2014 21:27:11 -0700 Subject: [PATCH 046/105] =?UTF-8?q?Specify=20branch=20support=20for=20mast?= =?UTF-8?q?er,=20add=20Gon=C3=A7alo=20to=20credits.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thank you!! <3 --- README.md | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index eda14eb..bde4cff 100755 --- a/README.md +++ b/README.md @@ -2,9 +2,15 @@ [![Build Status](https://travis-ci.org/zzak/acts_as_paranoid.png?branch=master)](https://travis-ci.org/zzak/acts_as_paranoid) -A simple plugin which hides records instead of deleting them, being able to recover them. +A Rails plugin to add soft delte. -**This branch targets Rails 3.2.** If you're working with another version, switch to the corresponding branch. +This gem can be used to hide records instead of deleting them, making them recoverable later. + +## Support + +**This branch targets Rails 3.2+.** + +If you're working with another version, switch to the corresponding branch, or require an older version of the acts_as_paranoid gem. ## Usage @@ -212,30 +218,6 @@ Watch out for these caveats: - You cannot name association `*_with_deleted` - `unscoped` will return all records, deleted or not -# Support - -This gem supports the most recent versions of Rails and Ruby. - -## Rails - -For Rails 3.2 check the README at the [rails3.2](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.2) branch and add this to your Gemfile: - - gem "acts_as_paranoid", "~> 0.4.0" - -For Rails 3.1 check the README at the [rails3.1](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.1) branch and add this to your Gemfile: - - gem "rails3_acts_as_paranoid", "~>0.1.4" - -For Rails 3.0 check the README at the [rails3.0](https://github.com/goncalossilva/rails3_acts_as_paranoid/tree/rails3.0) branch and add this to your Gemfile: - - gem "rails3_acts_as_paranoid", "~>0.0.9" - - -## Ruby - -This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode). - - # Acknowledgements * To [cheerfulstoic](https://github.com/cheerfulstoic) for adding recursive recovery @@ -245,6 +227,7 @@ This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode). * To [vikramdhillon](https://github.com/vikramdhillon) for the idea and initial implementation of support for string column type * To [Craig Walker](https://github.com/softcraft-development) for Rails 3.1 support and fixing various pending issues * To [Charles G.](https://github.com/chuckg) for Rails 3.2 support and for making a desperately needed global code refactoring +* To [Gonçalo Silva](https://github.com/goncalossilva) for supporting this gem prior to v0.4.3 ## Credits From f53f13b330596e2cb4c07e4f626463add53a1a6a Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sun, 10 Aug 2014 22:20:04 -0700 Subject: [PATCH 047/105] See `LICENSE`. --- README.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/README.md b/README.md index bde4cff..f24d667 100755 --- a/README.md +++ b/README.md @@ -229,11 +229,4 @@ Watch out for these caveats: * To [Charles G.](https://github.com/chuckg) for Rails 3.2 support and for making a desperately needed global code refactoring * To [Gonçalo Silva](https://github.com/goncalossilva) for supporting this gem prior to v0.4.3 -## Credits - -This plugin was inspired by [acts_as_paranoid](http://github.com/technoweenie/acts_as_paranoid) and [acts_as_active](http://github.com/fernandoluizao/acts_as_active). - -While porting it to Rails 3, I decided to apply the ideas behind those plugins to an unified solution while removing a **lot** of the complexity found in them. I eventually ended up writing a new plugin from scratch. - - -Copyright © 2014 Zachary Scott, Gonçalo Silva, Rick Olson, released under the MIT license +See `LICENSE`. From 7cb5ccd7534686df3be72539a3797d4c6c3a155b Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sun, 10 Aug 2014 22:21:29 -0700 Subject: [PATCH 048/105] Update homepage --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index a44a119..e9a9983 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |spec| spec.email = ["e@zzak.io"] spec.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." spec.description = "Check the home page for more in-depth information." - spec.homepage = "https://github.com/zzak/acts_as_paranoid" + spec.homepage = "https://github.com/technoweenie/acts_as_paranoid" spec.license = "MIT" spec.files = Dir["{lib}/**/*.rb", "LICENSE", "*.md"] From ed2a82ea34952922f79ff37f6dd824cb193c03bf Mon Sep 17 00:00:00 2001 From: Jon Daniel Date: Thu, 21 Aug 2014 13:34:33 -0400 Subject: [PATCH 049/105] Fixed minor spelling mistake --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f24d667..f485ff2 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build Status](https://travis-ci.org/zzak/acts_as_paranoid.png?branch=master)](https://travis-ci.org/zzak/acts_as_paranoid) -A Rails plugin to add soft delte. +A Rails plugin to add soft delete. This gem can be used to hide records instead of deleting them, making them recoverable later. From 75a4662c4ea6481c89194f905d8bdebca17efd12 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 14:28:31 -0700 Subject: [PATCH 050/105] rm 1.8 support, test against ruby-head --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 68410fb..ac25e68 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,14 @@ language: ruby rvm: - - 1.8.7 - 1.9.3 - 2.0.0 - 2.1 + - ruby-head - jruby - rbx matrix: allow_failures: + - rvm: ruby-head - rvm: rbx - rvm: jruby fast_finish: true From 2b5fa8208e938643014f8c14f12d1a612b4176e9 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 14:29:09 -0700 Subject: [PATCH 051/105] Target AR 4.x --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index e9a9983..57b0109 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |spec| spec.required_rubygems_version = ">= 1.3.6" - spec.add_dependency "activerecord", "~> 3.2" + spec.add_dependency "activerecord", "~> 4.0" spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" From 6f7fa0356dee97f88a83ac456aa1eb32eadf1096 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 14:29:57 -0700 Subject: [PATCH 052/105] This branch targets 4.x --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f485ff2..c6be185 100755 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This gem can be used to hide records instead of deleting them, making them recov ## Support -**This branch targets Rails 3.2+.** +**This branch targets Rails 4.x.** If you're working with another version, switch to the corresponding branch, or require an older version of the acts_as_paranoid gem. From 18d9ec4dba598761868b951a2ccc29f92df71269 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 16:02:48 -0700 Subject: [PATCH 053/105] Thank you @technoweenie!! <3 <3 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c6be185..58a5fd7 100755 --- a/README.md +++ b/README.md @@ -220,6 +220,7 @@ Watch out for these caveats: # Acknowledgements +* To [Rick Olson](https://github.com/technoweenie) for creating acts_as_paranoid * To [cheerfulstoic](https://github.com/cheerfulstoic) for adding recursive recovery * To [Jonathan Vaught](https://github.com/gravelpup) for adding paranoid validations * To [Geoffrey Hichborn](https://github.com/phene) for improving the overral code quality and adding support for after_commit From f672e87ac0cb0da202bec1fbecb70e1bdfb14cd0 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 16:03:02 -0700 Subject: [PATCH 054/105] Update repository homepage to org --- README.md | 2 +- acts_as_paranoid.gemspec | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 58a5fd7..c61f658 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ActsAsParanoid -[![Build Status](https://travis-ci.org/zzak/acts_as_paranoid.png?branch=master)](https://travis-ci.org/zzak/acts_as_paranoid) +[![Build Status](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid.png?branch=master)](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid) A Rails plugin to add soft delete. diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 57b0109..4fb33a5 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -6,11 +6,11 @@ require 'acts_as_paranoid/version' Gem::Specification.new do |spec| spec.name = "acts_as_paranoid" spec.version = ActsAsParanoid::VERSION - spec.authors = ["Zachary Scott", "André Medeiros", "Goncalo Silva", "Charles G.", "Rick Olson"] + spec.authors = ["Zachary Scott", "Goncalo Silva", "Rick Olson"] spec.email = ["e@zzak.io"] spec.summary = "Active Record plugin which allows you to hide and restore records without actually deleting them." spec.description = "Check the home page for more in-depth information." - spec.homepage = "https://github.com/technoweenie/acts_as_paranoid" + spec.homepage = "https://github.com/ActsAsParanoid/acts_as_paranoid" spec.license = "MIT" spec.files = Dir["{lib}/**/*.rb", "LICENSE", "*.md"] From 6bb32b23d709fb042ee17f643071f36b726a2c8e Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 16:06:24 -0700 Subject: [PATCH 055/105] build travis From 7057280281fc2af0f5f96a3461d40a19a035f3ca Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 16:49:49 -0700 Subject: [PATCH 056/105] Initial test matrix setup for AR 4+ on travis --- .travis.yml | 6 ++++++ Gemfile | 3 --- Rakefile | 21 +++++++++++++++++++-- acts_as_paranoid.gemspec | 1 + gemfiles/active_record_40.gemfile | 25 +++++++++++++++++++++++++ gemfiles/active_record_41.gemfile | 25 +++++++++++++++++++++++++ gemfiles/active_record_42.gemfile | 25 +++++++++++++++++++++++++ gemfiles/active_record_edge.gemfile | 29 +++++++++++++++++++++++++++++ 8 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 gemfiles/active_record_40.gemfile create mode 100644 gemfiles/active_record_41.gemfile create mode 100644 gemfiles/active_record_42.gemfile create mode 100644 gemfiles/active_record_edge.gemfile diff --git a/.travis.yml b/.travis.yml index ac25e68..e1c0ed2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,15 @@ rvm: - ruby-head - jruby - rbx +gemfile: + - gemfiles/active_record_40.gemfile + - gemfiles/active_record_41.gemfile + - gemfiles/active_record_42.gemfile + - gemfiles/active_record_edge.gemfile matrix: allow_failures: - rvm: ruby-head - rvm: rbx - rvm: jruby + - gemfile: gemfiles/active_record_edge.gemfile fast_finish: true diff --git a/Gemfile b/Gemfile index 9f25015..a1a1fbf 100644 --- a/Gemfile +++ b/Gemfile @@ -2,9 +2,6 @@ source "https://rubygems.org" # Development dependencies group :development do - gem "activerecord", "~> 3.2", :require => "active_record" - gem "activesupport", "~> 3.2", :require => "active_support" - gem "sqlite3", :platforms => [:ruby] gem "activerecord-jdbcsqlite3-adapter", :platforms => [:jruby] end diff --git a/Rakefile b/Rakefile index 40472ed..9f9a673 100755 --- a/Rakefile +++ b/Rakefile @@ -6,9 +6,26 @@ require "rdoc/task" gemspec = eval(File.read(Dir["*.gemspec"].first)) desc 'Default: run unit tests.' -task :default => :test +task :default => "test:all" + +namespace :test do + %w(active_record_edge active_record_40 active_record_41 active_record_42) do |version| + desc "Test acts_as_paranoid against #{version}" + task version do + sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle --quiet" + sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle exec rake -t test" + end + end + + desc "Run all tests for acts_as_paranoid" + task :all do + %w(active_record_edge active_record_40 active_record_41 active_record_42) do |version| + sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle --quiet" + sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle exec rake -t test" + end + end +end -desc 'Test the acts_as_paranoid plugin.' Rake::TestTask.new(:test) do |t| t.libs << 'test' t.pattern = 'test/test_*.rb' diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 4fb33a5..fae7f73 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -20,6 +20,7 @@ Gem::Specification.new do |spec| spec.required_rubygems_version = ">= 1.3.6" spec.add_dependency "activerecord", "~> 4.0" + spec.add_dependency "activesupport", "~> 4.0" spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" diff --git a/gemfiles/active_record_40.gemfile b/gemfiles/active_record_40.gemfile new file mode 100644 index 0000000..19c08f5 --- /dev/null +++ b/gemfiles/active_record_40.gemfile @@ -0,0 +1,25 @@ +source 'https://rubygems.org' + +gem 'activerecord', '~> 4.0.0', :require => 'active_record' +gem 'activesupport', '~> 4.0.0', :require => 'active_support' + +platforms :ruby do + if RUBY_VERSION > "2.1.0" + gem 'sqlite3' + else + gem 'sqlite3', '1.3.8' + end +end + +platforms :jruby do + gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' +end + +platforms :rbx do + gem 'rubysl', '~> 2.0' + gem 'racc' + gem 'rubysl-test-unit' + gem 'rubinius-developer_tools' +end + +gemspec :path => '../' diff --git a/gemfiles/active_record_41.gemfile b/gemfiles/active_record_41.gemfile new file mode 100644 index 0000000..cf062f7 --- /dev/null +++ b/gemfiles/active_record_41.gemfile @@ -0,0 +1,25 @@ +source 'https://rubygems.org' + +gem 'activerecord', '~> 4.1.0', :require => 'active_record' +gem 'activesupport', '~> 4.1.0', :require => 'active_support' + +platforms :ruby do + if RUBY_VERSION > "2.1.0" + gem 'sqlite3' + else + gem 'sqlite3', '1.3.8' + end +end + +platforms :jruby do + gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' +end + +platforms :rbx do + gem 'rubysl', '~> 2.0' + gem 'racc' + gem 'minitest' + gem 'rubinius-developer_tools' +end + +gemspec :path => '../' diff --git a/gemfiles/active_record_42.gemfile b/gemfiles/active_record_42.gemfile new file mode 100644 index 0000000..30ece1b --- /dev/null +++ b/gemfiles/active_record_42.gemfile @@ -0,0 +1,25 @@ +source 'https://rubygems.org' + +gem 'activerecord', '~> 4.2.0.beta1', :require => 'active_record' +gem 'activesupport', '~> 4.2.0.beta1', :require => 'active_support' + +platforms :ruby do + if RUBY_VERSION > "2.1.0" + gem 'sqlite3' + else + gem 'sqlite3', '1.3.8' + end +end + +platforms :jruby do + gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' +end + +platforms :rbx do + gem 'rubysl', '~> 2.0' + gem 'racc' + gem 'minitest' + gem 'rubinius-developer_tools' +end + +gemspec :path => '../' diff --git a/gemfiles/active_record_edge.gemfile b/gemfiles/active_record_edge.gemfile new file mode 100644 index 0000000..360778a --- /dev/null +++ b/gemfiles/active_record_edge.gemfile @@ -0,0 +1,29 @@ +source 'https://rubygems.org' + +git 'git://github.com/rails/rails.git' do + gem 'activerecord', :require => 'active_record' + gem 'activesupport', :require => 'active_support' +end + +gem 'arel', :github => 'rails/arel' + +platforms :ruby do + if RUBY_VERSION > "2.1.0" + gem 'sqlite3' + else + gem 'sqlite3', '1.3.8' + end +end + +platforms :jruby do + gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0' +end + +platforms :rbx do + gem 'rubysl', '~> 2.0' + gem 'racc' + gem 'minitest' + gem 'rubinius-developer_tools' +end + +gemspec :path => '../' From 82845baf75eb97ed00c664bcb4e15f68dca1b215 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 16:52:38 -0700 Subject: [PATCH 057/105] Fix typo in version iteration of Rakefile --- Rakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index 9f9a673..47167de 100755 --- a/Rakefile +++ b/Rakefile @@ -9,7 +9,7 @@ desc 'Default: run unit tests.' task :default => "test:all" namespace :test do - %w(active_record_edge active_record_40 active_record_41 active_record_42) do |version| + %w(active_record_edge active_record_40 active_record_41 active_record_42).each do |version| desc "Test acts_as_paranoid against #{version}" task version do sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle --quiet" @@ -19,7 +19,7 @@ namespace :test do desc "Run all tests for acts_as_paranoid" task :all do - %w(active_record_edge active_record_40 active_record_41 active_record_42) do |version| + %w(active_record_edge active_record_40 active_record_41 active_record_42).each do |version| sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle --quiet" sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle exec rake -t test" end From 5bf262e4b66d09117451fd2f32ed291110f68a18 Mon Sep 17 00:00:00 2001 From: Yuki Nishijima Date: Tue, 19 Mar 2013 19:40:30 +0900 Subject: [PATCH 058/105] belongs_to_with_deleted should pass scope to belongs_to_without_deleted --- lib/acts_as_paranoid/associations.rb | 6 +++--- test/test_associations.rb | 7 +++++++ test/test_helper.rb | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/acts_as_paranoid/associations.rb b/lib/acts_as_paranoid/associations.rb index bbf6fe4..3a9773a 100644 --- a/lib/acts_as_paranoid/associations.rb +++ b/lib/acts_as_paranoid/associations.rb @@ -8,9 +8,9 @@ class << base end module ClassMethods - def belongs_to_with_deleted(target, options = {}) - with_deleted = options.delete(:with_deleted) - result = belongs_to_without_deleted(target, options) + def belongs_to_with_deleted(target, scope = nil, options = {}) + with_deleted = (scope.is_a?(Hash) ? scope : options).delete(:with_deleted) + result = belongs_to_without_deleted(target, scope, options) if with_deleted result.options[:with_deleted] = with_deleted diff --git a/test/test_associations.rb b/test/test_associations.rb index a1f1c27..8a23a17 100644 --- a/test/test_associations.rb +++ b/test/test_associations.rb @@ -32,6 +32,13 @@ def test_removal_with_associations assert_equal 0, ParanoidProduct.with_deleted.count end + def test_belongs_to_with_scope_option + paranoid_has_many_dependant = ParanoidHasManyDependant.new + includes_values = ParanoidTime.includes(:not_paranoid).includes_values + + assert_equal includes_values, paranoid_has_many_dependant.association(:paranoid_time_with_scope).scope.includes_values + end + def test_belongs_to_with_deleted paranoid_time = ParanoidTime.first paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants.create(:name => 'dependant!') diff --git a/test/test_helper.rb b/test/test_helper.rb index 41cf228..4879b97 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -233,6 +233,7 @@ class DoubleHasOneNotParanoid < HasOneNotParanoid class ParanoidHasManyDependant < ActiveRecord::Base acts_as_paranoid belongs_to :paranoid_time + belongs_to :paranoid_time_with_scope, -> { includes(:not_paranoid) }, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id belongs_to :paranoid_time_with_deleted, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id, :with_deleted => true belongs_to :paranoid_time_polymorphic_with_deleted, :class_name => 'ParanoidTime', :foreign_key => :paranoid_time_id, :polymorphic => true, :with_deleted => true From e796b9f0345074964f5a5a23582466973b7cf965 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 10 May 2013 20:33:59 -0400 Subject: [PATCH 059/105] don't save when destroying a non persisted object --- test/test_core.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/test_core.rb b/test/test_core.rb index 207d662..5c842d5 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -77,6 +77,10 @@ def test_non_persisted_destroy! assert_not_nil pt.paranoid_value end + def test_removal_not_persisted + assert ParanoidTime.new.destroy + end + def test_recovery assert_equal 3, ParanoidBoolean.count ParanoidBoolean.first.destroy From ec9c311f14342bd1eac0f0cb4fb46c661782a1a9 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 25 Feb 2013 22:27:50 -0500 Subject: [PATCH 060/105] Rails 4.0.0 compatibility - Get rid of observers tests (I tried to use rails-observer gems but it was a mess) - Update deprecated calls like #scope or #default_scope without block - Get rid of attr_protected call and tests - Get rid of AR#destroy! NoMethodError test The last one cause issue because in AR 4 #destroy! bang is defined. It's the same as #destroy but raise an AR::RecordNotFound if the record is not present in database. It may be smart to find another name for this method. But for now it just works. Conflicts: Gemfile Gemfile.lock acts_as_paranoid.gemspec test/test_observers.rb --- lib/acts_as_paranoid/core.rb | 10 +++++----- lib/acts_as_paranoid/relation.rb | 2 +- test/test_core.rb | 3 +-- test/test_helper.rb | 27 ++------------------------- test/test_observers.rb | 16 ---------------- 5 files changed, 9 insertions(+), 49 deletions(-) delete mode 100644 test/test_observers.rb diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 3aa3c34..f02a155 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -34,16 +34,16 @@ def delete_all!(conditions = nil) end def delete_all(conditions = nil) - update_all ["#{paranoid_configuration[:column]} = ?", delete_now_value], conditions + where(conditions).update_all(["#{paranoid_configuration[:column]} = ?", delete_now_value]) end def paranoid_default_scope_sql if string_type_with_deleted_value? - self.scoped.table[paranoid_column].eq(nil). - or(self.scoped.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value])). + self.all.table[paranoid_column].eq(nil). + or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value])). to_sql else - self.scoped.table[paranoid_column].eq(nil).to_sql + self.all.table[paranoid_column].eq(nil).to_sql end end @@ -74,7 +74,7 @@ def delete_now_value protected def without_paranoid_default_scope - scope = self.scoped.with_default_scope + scope = self.all.with_default_scope scope.where_values.delete(paranoid_default_scope_sql) scope diff --git a/lib/acts_as_paranoid/relation.rb b/lib/acts_as_paranoid/relation.rb index a79b35f..1a4397c 100644 --- a/lib/acts_as_paranoid/relation.rb +++ b/lib/acts_as_paranoid/relation.rb @@ -21,7 +21,7 @@ def delete_all!(conditions = nil) def delete_all(conditions = nil) if paranoid? - update_all(paranoid_deletion_attributes, conditions) + where(conditions).update_all(paranoid_deletion_attributes) else delete_all!(conditions) end diff --git a/test/test_core.rb b/test/test_core.rb index 5c842d5..c187b31 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -4,7 +4,6 @@ class ParanoidTest < ParanoidBaseTest def test_paranoid? assert !NotParanoid.paranoid? assert_raise(NoMethodError) { NotParanoid.delete_all! } - assert_raise(NoMethodError) { NotParanoid.first.destroy! } assert_raise(NoMethodError) { NotParanoid.with_deleted } assert_raise(NoMethodError) { NotParanoid.only_deleted } @@ -60,7 +59,7 @@ def test_real_removal ParanoidTime.delete_all! assert_empty ParanoidTime.all - assert_empty ParanoidTime.with_deleted.all + assert_empty ParanoidTime.with_deleted end def test_non_persisted_destroy diff --git a/test/test_helper.rb b/test/test_helper.rb index 4879b97..12d64b2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -324,25 +324,6 @@ class InheritedParanoid < SuperParanoid acts_as_paranoid end -class ParanoidObserver < ActiveRecord::Observer - observe :paranoid_with_callback - - attr_accessor :called_before_recover, :called_after_recover - - def before_recover(paranoid_object) - self.called_before_recover = paranoid_object - end - - def after_recover(paranoid_object) - self.called_after_recover = paranoid_object - end - - def reset - self.called_before_recover = nil - self.called_after_recover = nil - end -end - class ParanoidManyManyParentLeft < ActiveRecord::Base has_many :paranoid_many_many_children @@ -365,8 +346,6 @@ class ParanoidWithScopedValidation < ActiveRecord::Base validates_uniqueness_of :name, :scope => :category end -ParanoidWithCallback.add_observer(ParanoidObserver.instance) - class ParanoidBaseTest < ActiveSupport::TestCase def setup setup_db @@ -379,8 +358,6 @@ def setup ParanoidString.create! :name => "strings can be paranoid" NotParanoid.create! :name => "no paranoid goals" ParanoidWithCallback.create! :name => "paranoid with callbacks" - - ParanoidObserver.instance.reset end def teardown @@ -416,7 +393,7 @@ class ParanoidForest < ActiveRecord::Base require "active_support/core_ext/logger.rb" ActiveRecord::Base.logger = Logger.new(StringIO.new) - scope :rainforest, where(:rainforest => true) + scope :rainforest, lambda{ where(:rainforest => true) } has_many :paranoid_trees, :dependent => :destroy end @@ -429,7 +406,7 @@ class ParanoidTree < ActiveRecord::Base class ParanoidHuman < ActiveRecord::Base acts_as_paranoid - default_scope where('gender = ?', 'male') + default_scope { where('gender = ?', 'male') } end class ParanoidAndroid < ActiveRecord::Base diff --git a/test/test_observers.rb b/test/test_observers.rb deleted file mode 100644 index 6a60efe..0000000 --- a/test/test_observers.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'test_helper' - -class ParanoidObserverTest < ParanoidBaseTest - def test_called_observer_methods - @subject = ParanoidWithCallback.new - @subject.save - - assert_nil ParanoidObserver.instance.called_before_recover - assert_nil ParanoidObserver.instance.called_after_recover - - ParanoidWithCallback.find(@subject.id).recover - - assert_equal @subject, ParanoidObserver.instance.called_before_recover - assert_equal @subject, ParanoidObserver.instance.called_after_recover - end -end From d5c17ad94757e9919efdef38187d0bb3e27f52d4 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 17:08:11 -0700 Subject: [PATCH 061/105] Merged in @byroot's Rails 4.0.0 support, thank you! <3 <3 <3 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c61f658..aceb1f1 100755 --- a/README.md +++ b/README.md @@ -229,5 +229,6 @@ Watch out for these caveats: * To [Craig Walker](https://github.com/softcraft-development) for Rails 3.1 support and fixing various pending issues * To [Charles G.](https://github.com/chuckg) for Rails 3.2 support and for making a desperately needed global code refactoring * To [Gonçalo Silva](https://github.com/goncalossilva) for supporting this gem prior to v0.4.3 +* To [Jean Boussier](https://github.com/byroot) for initial Rails 4.0.0 support See `LICENSE`. From c6d7c28b79fef3bb846b1d8138e4674ff25c6205 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 25 Aug 2014 17:19:31 -0700 Subject: [PATCH 062/105] Add travis script for test --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index e1c0ed2..d7c19ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: ruby +script: "bundle exec rake test" rvm: - 1.9.3 - 2.0.0 From 115f7623975d407b1023476ba81e43ea28f8eaba Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Tue, 26 Aug 2014 11:36:25 -0700 Subject: [PATCH 063/105] bump to beta1 --- lib/acts_as_paranoid/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/version.rb b/lib/acts_as_paranoid/version.rb index bdf0c3a..00fc7c2 100644 --- a/lib/acts_as_paranoid/version.rb +++ b/lib/acts_as_paranoid/version.rb @@ -1,3 +1,3 @@ module ActsAsParanoid - VERSION = "0.5.0.beta" + VERSION = "0.5.0.beta1" end From d7929c0cc4b607349232d4d7a874cc6997367420 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 29 Aug 2014 14:18:47 -0700 Subject: [PATCH 064/105] result is a hash --- lib/acts_as_paranoid/associations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/associations.rb b/lib/acts_as_paranoid/associations.rb index 3a9773a..6a6e0a0 100644 --- a/lib/acts_as_paranoid/associations.rb +++ b/lib/acts_as_paranoid/associations.rb @@ -13,7 +13,7 @@ def belongs_to_with_deleted(target, scope = nil, options = {}) result = belongs_to_without_deleted(target, scope, options) if with_deleted - result.options[:with_deleted] = with_deleted + result[:with_deleted] = with_deleted unless method_defined? "#{target}_with_unscoped" class_eval <<-RUBY, __FILE__, __LINE__ def #{target}_with_unscoped(*args) From 9fdd810cb9d89f34cbbc51a7acfcffba68741010 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 29 Aug 2014 14:25:48 -0700 Subject: [PATCH 065/105] Don't eager load logger, we no longer support 1.8.7 anyways --- test/test_helper.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index 12d64b2..3b77dd2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -389,8 +389,6 @@ def find_row(model) class ParanoidForest < ActiveRecord::Base acts_as_paranoid - # HACK: scope throws an error on 1.8.7 because the logger isn't initialized (see https://github.com/Casecommons/pg_search/issues/26) - require "active_support/core_ext/logger.rb" ActiveRecord::Base.logger = Logger.new(StringIO.new) scope :rainforest, lambda{ where(:rainforest => true) } From 6142210585e3f88af344620f9672d7d5bf7345be Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 29 Aug 2014 14:29:16 -0700 Subject: [PATCH 066/105] Use unscoped instead of with_default_scope --- lib/acts_as_paranoid/core.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index f02a155..06b7eed 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -74,7 +74,7 @@ def delete_now_value protected def without_paranoid_default_scope - scope = self.all.with_default_scope + scope = self.all.unscoped scope.where_values.delete(paranoid_default_scope_sql) scope From eef6a4f3fe2014ea2c515c55b035e2952c211bb5 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 29 Aug 2014 14:53:11 -0700 Subject: [PATCH 067/105] serialized_attributes has been deprecated in rails/rails#15704 --- lib/acts_as_paranoid/validations.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/acts_as_paranoid/validations.rb b/lib/acts_as_paranoid/validations.rb index 5db78df..1f90c8c 100644 --- a/lib/acts_as_paranoid/validations.rb +++ b/lib/acts_as_paranoid/validations.rb @@ -11,10 +11,10 @@ def validate_each(record, attribute, value) finder_class = find_finder_class_for(record) table = finder_class.arel_table - coder = record.class.serialized_attributes[attribute.to_s] + coder = record.class.type_for_attribute(attribute.to_s) if value && coder - value = coder.dump value + value = coder.type_cast_for_database value end relation = build_relation(finder_class, table, attribute, value) From ddcd1915179c73f74985af6bc8935321ca2fe08d Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 29 Aug 2014 14:53:48 -0700 Subject: [PATCH 068/105] Use timestamps with null: false --- test/test_helper.rb | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index 3b77dd2..7f968ab 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -24,7 +24,7 @@ def setup_db t.integer :paranoid_belongs_dependant_id t.integer :not_paranoid_id - t.timestamps + timestamps t end create_table :paranoid_booleans do |t| @@ -32,7 +32,7 @@ def setup_db t.boolean :is_deleted t.integer :paranoid_time_id - t.timestamps + timestamps t end create_table :paranoid_strings do |t| @@ -44,14 +44,14 @@ def setup_db t.string :name t.integer :paranoid_time_id - t.timestamps + timestamps t end create_table :has_one_not_paranoids do |t| t.string :name t.integer :paranoid_time_id - t.timestamps + timestamps t end create_table :paranoid_has_many_dependants do |t| @@ -61,14 +61,14 @@ def setup_db t.string :paranoid_time_polymorphic_with_deleted_type t.integer :paranoid_belongs_dependant_id - t.timestamps + timestamps t end create_table :paranoid_belongs_dependants do |t| t.string :name t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_has_one_dependants do |t| @@ -76,28 +76,28 @@ def setup_db t.datetime :deleted_at t.integer :paranoid_boolean_id - t.timestamps + timestamps t end create_table :paranoid_with_callbacks do |t| t.string :name t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_destroy_companies do |t| t.string :name t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_delete_companies do |t| t.string :name t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_products do |t| @@ -106,7 +106,7 @@ def setup_db t.string :name t.datetime :deleted_at - t.timestamps + timestamps t end create_table :super_paranoids do |t| @@ -114,38 +114,38 @@ def setup_db t.references :has_many_inherited_super_paranoidz t.datetime :deleted_at - t.timestamps + timestamps t end create_table :has_many_inherited_super_paranoidzs do |t| t.references :super_paranoidz t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_many_many_parent_lefts do |t| t.string :name - t.timestamps + timestamps t end create_table :paranoid_many_many_parent_rights do |t| t.string :name - t.timestamps + timestamps t end create_table :paranoid_many_many_children do |t| t.integer :paranoid_many_many_parent_left_id t.integer :paranoid_many_many_parent_right_id t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_with_scoped_validations do |t| t.string :name t.string :category t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_forests do |t| @@ -153,7 +153,7 @@ def setup_db t.boolean :rainforest t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_trees do |t| @@ -161,14 +161,14 @@ def setup_db t.string :name t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_humen do |t| t.string :gender t.datetime :deleted_at - t.timestamps + timestamps t end create_table :paranoid_androids do |t| @@ -184,6 +184,11 @@ def setup_db end end +def timestamps(table) + table.column :created_at , :timestamp, :null => false + table.column :updated_at , :timestamp, :null => false +end + def teardown_db ActiveRecord::Base.connection.tables.each do |table| ActiveRecord::Base.connection.drop_table(table) From e01409418536a926d08fd21c785cbe2ed197e7c7 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Tue, 18 Nov 2014 20:24:11 +0100 Subject: [PATCH 069/105] Use minitest version compatible with other dependencies --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index fae7f73..7686441 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -25,5 +25,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" spec.add_development_dependency "rdoc" - spec.add_development_dependency "minitest", "~> 4.0" + spec.add_development_dependency "minitest", "~> 5.4" end From fd4e16e0a8dd7180edac83373e9dfecf4f383f00 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Tue, 18 Nov 2014 20:41:22 +0100 Subject: [PATCH 070/105] Use #column_types instead of #type_for_attribute --- lib/acts_as_paranoid/validations.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/acts_as_paranoid/validations.rb b/lib/acts_as_paranoid/validations.rb index 1f90c8c..3fe26ff 100644 --- a/lib/acts_as_paranoid/validations.rb +++ b/lib/acts_as_paranoid/validations.rb @@ -11,10 +11,11 @@ def validate_each(record, attribute, value) finder_class = find_finder_class_for(record) table = finder_class.arel_table - coder = record.class.type_for_attribute(attribute.to_s) + # TODO: Use record.class.column_types[attribute.to_s].coder ? + coder = record.class.column_types[attribute.to_s] if value && coder - value = coder.type_cast_for_database value + value = coder.type_cast_for_write value end relation = build_relation(finder_class, table, attribute, value) From e8f7fbb1004c010e87cd11e648a914621c367043 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Tue, 18 Nov 2014 20:50:49 +0100 Subject: [PATCH 071/105] Do not mangle belongs_to result The values of the result hash are all reflection objects. Adding a boolean there breaks stuff. --- lib/acts_as_paranoid/associations.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/acts_as_paranoid/associations.rb b/lib/acts_as_paranoid/associations.rb index 6a6e0a0..d4e6ac7 100644 --- a/lib/acts_as_paranoid/associations.rb +++ b/lib/acts_as_paranoid/associations.rb @@ -13,7 +13,6 @@ def belongs_to_with_deleted(target, scope = nil, options = {}) result = belongs_to_without_deleted(target, scope, options) if with_deleted - result[:with_deleted] = with_deleted unless method_defined? "#{target}_with_unscoped" class_eval <<-RUBY, __FILE__, __LINE__ def #{target}_with_unscoped(*args) From a8953b52be79a7ea12fae5f5671d75a2ed05af69 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Tue, 18 Nov 2014 21:04:38 +0100 Subject: [PATCH 072/105] Set with_deleted option --- lib/acts_as_paranoid/associations.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/acts_as_paranoid/associations.rb b/lib/acts_as_paranoid/associations.rb index d4e6ac7..1c9076a 100644 --- a/lib/acts_as_paranoid/associations.rb +++ b/lib/acts_as_paranoid/associations.rb @@ -13,6 +13,7 @@ def belongs_to_with_deleted(target, scope = nil, options = {}) result = belongs_to_without_deleted(target, scope, options) if with_deleted + result.values.last.options[:with_deleted] = with_deleted unless method_defined? "#{target}_with_unscoped" class_eval <<-RUBY, __FILE__, __LINE__ def #{target}_with_unscoped(*args) From 3bf46c2364b8d1256467211e92e6272a99f1e87a Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Tue, 18 Nov 2014 21:25:55 +0100 Subject: [PATCH 073/105] Fix with_deleted Remove #unscoped to avoid clearing the where_values prematurely. --- lib/acts_as_paranoid/core.rb | 2 +- test/test_associations.rb | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 06b7eed..0d1e83a 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -74,7 +74,7 @@ def delete_now_value protected def without_paranoid_default_scope - scope = self.all.unscoped + scope = self.all scope.where_values.delete(paranoid_default_scope_sql) scope diff --git a/test/test_associations.rb b/test/test_associations.rb index 8a23a17..398be66 100644 --- a/test/test_associations.rb +++ b/test/test_associations.rb @@ -108,6 +108,9 @@ def test_only_find_associated_records_when_finding_with_paranoid_deleted child.destroy assert_paranoid_deletion(child) + parent.reload + + assert_equal [], parent.paranoid_has_many_dependants.to_a assert_equal [child], parent.paranoid_has_many_dependants.with_deleted.to_a end From 3c12279a093eeebe22596a9db92eacb19ca5e62d Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 08:28:29 +0100 Subject: [PATCH 074/105] Soft destroy dependents The dependent destroy callback mechanism in Rails calls destroy! instead of destroy for has_many associations. With the existing implementation of acts_as_paranoid, this would unintentionally cause dependent objects to be hard-destroyed. This change makes destroy and destroy! identical, and adds a separate destroy_fully! method for full destroy. --- lib/acts_as_paranoid/core.rb | 10 +++++++--- test/test_core.rb | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 0d1e83a..1d37fb8 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -89,7 +89,7 @@ def paranoid_value self.send(self.class.paranoid_column) end - def destroy! + def destroy_fully! with_transaction_returning_status do run_callbacks :destroy do destroy_dependent_associations! @@ -101,7 +101,7 @@ def destroy! end end - def destroy + def destroy! if !deleted? with_transaction_returning_status do run_callbacks :destroy do @@ -112,10 +112,14 @@ def destroy end end else - destroy! + destroy_fully! end end + def destroy + destroy! + end + def recover(options={}) options = { :recursive => self.class.paranoid_configuration[:recover_dependent_associations], diff --git a/test/test_core.rb b/test/test_core.rb index c187b31..0c01dd0 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -144,6 +144,12 @@ def test_recursive_fake_removal assert_equal 0, ParanoidHasOneDependant.count assert_equal 1, NotParanoid.count assert_equal 0, HasOneNotParanoid.count + + assert_equal 3, ParanoidTime.with_deleted.count + assert_equal 4, ParanoidHasManyDependant.with_deleted.count + assert_equal 3, ParanoidBelongsDependant.with_deleted.count + assert_equal @paranoid_boolean_count + 3, ParanoidBoolean.with_deleted.count + assert_equal 3, ParanoidHasOneDependant.with_deleted.count end def test_recursive_real_removal From 421dd3d3e794daf526d2f10d5824d755ef0519c8 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 09:09:27 +0100 Subject: [PATCH 075/105] Fix dependent recoverable associations scope By merging the scope, the original code would re-apply the default non-deleted scope, causing the scope to always return zero records. Use regular scope chaining instead. --- lib/acts_as_paranoid/core.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 1d37fb8..482822d 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -148,7 +148,7 @@ def recover_dependent_associations(window, options) # We can only recover by window if both parent and dependant have a # paranoid column type of :time. if self.class.paranoid_column_type == :time && klass.paranoid_column_type == :time - scope = scope.merge(klass.deleted_inside_time_window(paranoid_value, window)) + scope = scope.deleted_inside_time_window(paranoid_value, window) end scope.each do |object| From 37a9e331884a2c66a482bdf28018a7aabe5ada44 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 09:22:30 +0100 Subject: [PATCH 076/105] Fix test to show dependent removal behavior --- test/test_associations.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/test_associations.rb b/test/test_associations.rb index 398be66..8fc1cd6 100644 --- a/test/test_associations.rb +++ b/test/test_associations.rb @@ -2,8 +2,6 @@ class AssociationsTest < ParanoidBaseTest def test_removal_with_associations - # This test shows that the current implementation doesn't handle - # assciation deletion correctly (when hard deleting via parent-object) paranoid_company_1 = ParanoidDestroyCompany.create! :name => "ParanoidDestroyCompany #1" paranoid_company_2 = ParanoidDeleteCompany.create! :name => "ParanoidDestroyCompany #1" paranoid_company_1.paranoid_products.create! :name => "ParanoidProduct #1" @@ -19,13 +17,19 @@ def test_removal_with_associations assert_equal 1, ParanoidDestroyCompany.with_deleted.count assert_equal 2, ParanoidProduct.with_deleted.count - ParanoidDestroyCompany.with_deleted.first.destroy! + ParanoidDestroyCompany.with_deleted.first.destroy assert_equal 0, ParanoidDestroyCompany.count assert_equal 1, ParanoidProduct.count assert_equal 0, ParanoidDestroyCompany.with_deleted.count assert_equal 1, ParanoidProduct.with_deleted.count - ParanoidDeleteCompany.with_deleted.first.destroy! + ParanoidDeleteCompany.first.destroy + assert_equal 0, ParanoidDeleteCompany.count + assert_equal 0, ParanoidProduct.count + assert_equal 1, ParanoidDeleteCompany.with_deleted.count + assert_equal 1, ParanoidProduct.with_deleted.count + + ParanoidDeleteCompany.with_deleted.first.destroy assert_equal 0, ParanoidDeleteCompany.count assert_equal 0, ParanoidProduct.count assert_equal 0, ParanoidDeleteCompany.with_deleted.count From 6d9981e747b3f40ca8bed06085b7939001dc566e Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 09:30:02 +0100 Subject: [PATCH 077/105] Use destroy_fully! where needed --- test/test_core.rb | 6 +++--- test/test_default_scopes.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_core.rb b/test/test_core.rb index 0c01dd0..cc189b5 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -40,9 +40,9 @@ def test_fake_removal end def test_real_removal - ParanoidTime.first.destroy! + ParanoidTime.first.destroy_fully! ParanoidBoolean.delete_all!("name = 'extremely paranoid' OR name = 'really paranoid'") - ParanoidString.first.destroy! + ParanoidString.first.destroy_fully! assert_equal 2, ParanoidTime.count assert_equal 1, ParanoidBoolean.count assert_equal 0, ParanoidString.count @@ -155,7 +155,7 @@ def test_recursive_fake_removal def test_recursive_real_removal setup_recursive_tests - @paranoid_time_object.destroy! + @paranoid_time_object.destroy_fully! assert_equal 0, ParanoidTime.only_deleted.count assert_equal 1, ParanoidHasManyDependant.only_deleted.count diff --git a/test/test_default_scopes.rb b/test/test_default_scopes.rb index 894ec8b..330ad93 100644 --- a/test/test_default_scopes.rb +++ b/test/test_default_scopes.rb @@ -37,7 +37,7 @@ def test_real_removal_with_multiple_default_scope assert_equal 0, ParanoidHuman.only_deleted.count assert_equal 3, ParanoidHuman.unscoped.count - ParanoidHuman.first.destroy! + ParanoidHuman.first.destroy_fully! assert_equal 1, ParanoidHuman.count assert_equal 1, ParanoidHuman.with_deleted.count assert_equal 0, ParanoidHuman.only_deleted.count From 97d3b009147f6c720f4e7d0c5146dd340492aeca Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 09:30:44 +0100 Subject: [PATCH 078/105] Allow broad range of minitest versions This is to avoid conflict with minitest versions required by the different versions of Rails. --- acts_as_paranoid.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 7686441..1a2f5b6 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -25,5 +25,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" spec.add_development_dependency "rdoc" - spec.add_development_dependency "minitest", "~> 5.4" + spec.add_development_dependency "minitest", ">= 4.0", "<= 6.0" end From 9c70f8c962590d086dc0d95e9a79423fcc9456e1 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 11:58:36 +0100 Subject: [PATCH 079/105] Munge result of belongs_to differently for AR 4.0 --- lib/acts_as_paranoid/associations.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/associations.rb b/lib/acts_as_paranoid/associations.rb index 1c9076a..aa5a563 100644 --- a/lib/acts_as_paranoid/associations.rb +++ b/lib/acts_as_paranoid/associations.rb @@ -13,7 +13,12 @@ def belongs_to_with_deleted(target, scope = nil, options = {}) result = belongs_to_without_deleted(target, scope, options) if with_deleted - result.values.last.options[:with_deleted] = with_deleted + if result.is_a? Hash + result.values.last.options[:with_deleted] = with_deleted + else + result.options[:with_deleted] = with_deleted + end + unless method_defined? "#{target}_with_unscoped" class_eval <<-RUBY, __FILE__, __LINE__ def #{target}_with_unscoped(*args) From 01bdce8585e15d05de8c38fc874183e6df590c83 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 19:42:28 +0100 Subject: [PATCH 080/105] Fix #without_paranoid_default_scope on AR 4.0 --- lib/acts_as_paranoid/core.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 482822d..3152f9c 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -75,7 +75,13 @@ def delete_now_value def without_paranoid_default_scope scope = self.all - scope.where_values.delete(paranoid_default_scope_sql) + if scope.where_values.include? paranoid_default_scope_sql + # ActiveRecord 4.1 + scope.where_values.delete(paranoid_default_scope_sql) + else + scope = scope.with_default_scope + scope.where_values.delete(paranoid_default_scope_sql) + end scope end From ae6598cd2f2cd8ddfe8907473c1de871cb1916cd Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 21:22:13 +0100 Subject: [PATCH 081/105] Make #validate_each work with AR 4.2 --- lib/acts_as_paranoid/validations.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/validations.rb b/lib/acts_as_paranoid/validations.rb index 3fe26ff..d0dc80b 100644 --- a/lib/acts_as_paranoid/validations.rb +++ b/lib/acts_as_paranoid/validations.rb @@ -15,7 +15,11 @@ def validate_each(record, attribute, value) coder = record.class.column_types[attribute.to_s] if value && coder - value = coder.type_cast_for_write value + value = if coder.respond_to? :type_cast_for_database + coder.type_cast_for_database value + else + coder.type_cast_for_write value + end end relation = build_relation(finder_class, table, attribute, value) From 784a874c08445ac7c45a18bac8d7755754cb5258 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 21:28:57 +0100 Subject: [PATCH 082/105] Fix tests to allow reflections hash keys to be strings --- test/test_associations.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_associations.rb b/test/test_associations.rb index 8fc1cd6..55b0a79 100644 --- a/test/test_associations.rb +++ b/test/test_associations.rb @@ -83,19 +83,19 @@ def test_belongs_to_nil_polymorphic_with_deleted end def test_belongs_to_options - paranoid_time = ParanoidHasManyDependant.reflections[:paranoid_time] + paranoid_time = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time] assert_equal :belongs_to, paranoid_time.macro assert_nil paranoid_time.options[:with_deleted] end def test_belongs_to_with_deleted_options - paranoid_time_with_deleted = ParanoidHasManyDependant.reflections[:paranoid_time_with_deleted] + paranoid_time_with_deleted = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time_with_deleted] assert_equal :belongs_to, paranoid_time_with_deleted.macro assert paranoid_time_with_deleted.options[:with_deleted] end def test_belongs_to_polymorphic_with_deleted_options - paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections[:paranoid_time_polymorphic_with_deleted] + paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time_polymorphic_with_deleted] assert_equal :belongs_to, paranoid_time_polymorphic_with_deleted.macro assert paranoid_time_polymorphic_with_deleted.options[:with_deleted] end From be7e251f869a2f29c35a8875f30ee1bd3eb76d84 Mon Sep 17 00:00:00 2001 From: Matijs van Zuijlen Date: Wed, 19 Nov 2014 21:45:41 +0100 Subject: [PATCH 083/105] Fix AR 4.2 deprecation warnings in tests --- test/test_relations.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_relations.rb b/test/test_relations.rb index ee00e51..bef6595 100644 --- a/test/test_relations.rb +++ b/test/test_relations.rb @@ -75,7 +75,7 @@ def test_associations_filtered_by_only_deleted def test_fake_removal_through_relation # destroy: through a relation. - ParanoidForest.rainforest.destroy(@paranoid_forest_3) + ParanoidForest.rainforest.destroy(@paranoid_forest_3.id) assert_equal 1, ParanoidForest.rainforest.count assert_equal 2, ParanoidForest.rainforest.with_deleted.count assert_equal 1, ParanoidForest.rainforest.only_deleted.count @@ -95,8 +95,8 @@ def test_real_removal_through_relation # destroy: two-step through a relation paranoid_tree = @paranoid_forest_1.paranoid_trees.first - @paranoid_forest_1.paranoid_trees.order(:id).destroy(paranoid_tree) - @paranoid_forest_1.paranoid_trees.only_deleted.destroy(paranoid_tree) + @paranoid_forest_1.paranoid_trees.order(:id).destroy(paranoid_tree.id) + @paranoid_forest_1.paranoid_trees.only_deleted.destroy(paranoid_tree.id) assert_equal 1, @paranoid_forest_1.paranoid_trees(true).count assert_equal 1, @paranoid_forest_1.paranoid_trees(true).with_deleted.count assert_equal 0, @paranoid_forest_1.paranoid_trees(true).only_deleted.count From fa16de9dd1c96e3b45616558e796369a78be668f Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Tue, 5 Aug 2014 19:13:44 -0700 Subject: [PATCH 084/105] Update_all for delete_all recovery Conflicts: lib/acts_as_paranoid/core.rb --- lib/acts_as_paranoid/core.rb | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 3152f9c..7e720f1 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -40,8 +40,8 @@ def delete_all(conditions = nil) def paranoid_default_scope_sql if string_type_with_deleted_value? self.all.table[paranoid_column].eq(nil). - or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value])). - to_sql + or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value])). + to_sql else self.all.table[paranoid_column].eq(nil).to_sql end @@ -60,18 +60,21 @@ def paranoid_column_type end def dependent_associations - self.reflect_on_all_associations.select {|a| [:destroy, :delete_all].include?(a.options[:dependent]) } + self.reflect_on_all_associations.select { |a| [:destroy, :delete_all].include?(a.options[:dependent]) } end def delete_now_value case paranoid_configuration[:column_type] - when "time" then Time.now - when "boolean" then true - when "string" then paranoid_configuration[:deleted_value] + when "time" then + Time.now + when "boolean" then + true + when "string" then + paranoid_configuration[:deleted_value] end end - protected + protected def without_paranoid_default_scope scope = self.all @@ -128,8 +131,8 @@ def destroy def recover(options={}) options = { - :recursive => self.class.paranoid_configuration[:recover_dependent_associations], - :recovery_window => self.class.paranoid_configuration[:dependent_recovery_window] + :recursive => self.class.paranoid_configuration[:recover_dependent_associations], + :recovery_window => self.class.paranoid_configuration[:dependent_recovery_window] }.merge(options) self.class.transaction do @@ -157,8 +160,12 @@ def recover_dependent_associations(window, options) scope = scope.deleted_inside_time_window(paranoid_value, window) end - scope.each do |object| - object.recover(options) + unless reflection.options[:dependent] == :delete_all + scope.each do |object| + object.recover(options) + end + else + scope.update_all(self.class.paranoid_column => nil) end end end @@ -180,7 +187,7 @@ def destroy_dependent_associations! def deleted? !(paranoid_value.nil? || - (self.class.string_type_with_deleted_value? && paranoid_value != self.class.delete_now_value)) + (self.class.string_type_with_deleted_value? && paranoid_value != self.class.delete_now_value)) end alias_method :destroyed?, :deleted? From a48781f4e06465ee584105d3e018f5ea2f3e2efc Mon Sep 17 00:00:00 2001 From: pavlos Date: Tue, 14 Apr 2015 10:34:20 -0700 Subject: [PATCH 085/105] removed extraneous "then" from case statement --- lib/acts_as_paranoid/core.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 7e720f1..a8c93fd 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -65,11 +65,11 @@ def dependent_associations def delete_now_value case paranoid_configuration[:column_type] - when "time" then + when "time" Time.now - when "boolean" then + when "boolean" true - when "string" then + when "string" paranoid_configuration[:deleted_value] end end From 273e741a491c47bf7fe39d8feecaa5340faa3779 Mon Sep 17 00:00:00 2001 From: pavlos Date: Tue, 14 Apr 2015 10:56:02 -0700 Subject: [PATCH 086/105] reimlemented Chris Chiu's changes "Added support for only propagating delete to paranoid associations" see: 51cc825c451fd80af4e5ca44b11f0e7cc37543f2 --- lib/acts_as_paranoid.rb | 2 +- lib/acts_as_paranoid/core.rb | 32 +++++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/acts_as_paranoid.rb b/lib/acts_as_paranoid.rb index 11bf5e4..0a9a49b 100644 --- a/lib/acts_as_paranoid.rb +++ b/lib/acts_as_paranoid.rb @@ -18,7 +18,7 @@ def acts_as_paranoid(options = {}) class_attribute :paranoid_configuration, :paranoid_column_reference - self.paranoid_configuration = { :column => "deleted_at", :column_type => "time", :recover_dependent_associations => true, :dependent_recovery_window => 2.minutes } + self.paranoid_configuration = { :column => "deleted_at", :column_type => "time", :recover_dependent_associations => true, :dependent_recovery_window => 2.minutes, :dependent_destroy_paranoid_only => false } self.paranoid_configuration.merge!({ :deleted_value => "deleted" }) if options[:column_type] == "string" self.paranoid_configuration.merge!(options) # user options diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index a8c93fd..86234a5 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -111,13 +111,19 @@ def destroy_fully! end def destroy! - if !deleted? + unless deleted? with_transaction_returning_status do - run_callbacks :destroy do - # Handle composite keys, otherwise we would just use `self.class.primary_key.to_sym => self.id`. - self.class.delete_all(Hash[[Array(self.class.primary_key), Array(self.id)].transpose]) if persisted? + if self.class.paranoid_configuration[:dependent_destroy_paranoid_only] + destroy_paranoid_associations self.paranoid_value = self.class.delete_now_value - self + self.save! + else + run_callbacks :destroy do + # Handle composite keys, otherwise we would just use `self.class.primary_key.to_sym => self.id`. + self.class.delete_all(Hash[[Array(self.class.primary_key), Array(self.id)].transpose]) if persisted? + self.paranoid_value = self.class.delete_now_value + self + end end end else @@ -185,6 +191,22 @@ def destroy_dependent_associations! end end + def destroy_paranoid_associations + self.class.dependent_associations.each do |reflection| + if reflection.klass.paranoid? + dependent_type = reflection.options[:dependent] + association_scope = association(reflection.name).association_scope + if dependent_type == :destroy + association_scope.each do |object| + object.send(reflection.options[:dependent]) + end + elsif dependent_type == :delete_all + association_scope.delete_all + end + end + end + end + def deleted? !(paranoid_value.nil? || (self.class.string_type_with_deleted_value? && paranoid_value != self.class.delete_now_value)) From 07bb0cdebb3e7c1141a135b587e03f4502caf15d Mon Sep 17 00:00:00 2001 From: pavlos Date: Tue, 14 Apr 2015 10:59:20 -0700 Subject: [PATCH 087/105] reimplemented Chris Chiu's change "Halt execution of recovery if callback returns false" see: cb800f218f0b674d398ee2b9c49718daf2664b44 --- lib/acts_as_paranoid/core.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 86234a5..8da1cf4 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -6,7 +6,7 @@ def self.included(base) module ClassMethods def self.extended(base) - base.define_callbacks :recover + base.define_callbacks :recover, terminator: 'result == false' end def before_recover(method) From 7891ea6362c89bb25383967e2ff00931c4142c2d Mon Sep 17 00:00:00 2001 From: pavlos Date: Tue, 14 Apr 2015 11:20:04 -0700 Subject: [PATCH 088/105] fixed string based terminator deprecation warning --- lib/acts_as_paranoid/core.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 8da1cf4..db9a387 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -6,7 +6,7 @@ def self.included(base) module ClassMethods def self.extended(base) - base.define_callbacks :recover, terminator: 'result == false' + base.define_callbacks :recover, terminator: lambda { |target, result| result == false } end def before_recover(method) From 316e98ae4f8c427f2ccc067f97973a899aa1614f Mon Sep 17 00:00:00 2001 From: pavlos Date: Tue, 14 Apr 2015 13:01:58 -0700 Subject: [PATCH 089/105] reimplemented Chris Chiu's change "Fixing cascading recover to recover the main model first and then its dependents" see: 60c236e32a09fbeba0996a40c251cffa2dbcbae6?diff=split --- lib/acts_as_paranoid/core.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index db9a387..78a1517 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -143,15 +143,16 @@ def recover(options={}) self.class.transaction do run_callbacks :recover do - recover_dependent_associations(options[:recovery_window], options) if options[:recursive] - + paranoid_original_value = self.paranoid_value self.paranoid_value = nil - self.save + self.save! + + recover_dependent_associations(paranoid_original_value, options[:recovery_window], options) if options[:recursive] end end end - def recover_dependent_associations(window, options) + def recover_dependent_associations(paranoid_original_value, window, options) self.class.dependent_associations.each do |reflection| next unless (klass = get_reflection_class(reflection)).paranoid? @@ -163,7 +164,7 @@ def recover_dependent_associations(window, options) # We can only recover by window if both parent and dependant have a # paranoid column type of :time. if self.class.paranoid_column_type == :time && klass.paranoid_column_type == :time - scope = scope.deleted_inside_time_window(paranoid_value, window) + scope = scope.deleted_inside_time_window(paranoid_original_value, window) end unless reflection.options[:dependent] == :delete_all From c2d914e5b968bb2a0f1960312164d83690487e41 Mon Sep 17 00:00:00 2001 From: pavlos Date: Thu, 11 Jun 2015 14:24:24 -0700 Subject: [PATCH 090/105] fix delete order --- lib/acts_as_paranoid/core.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 78a1517..507d29b 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -100,8 +100,8 @@ def paranoid_value def destroy_fully! with_transaction_returning_status do + destroy_dependent_associations! run_callbacks :destroy do - destroy_dependent_associations! # Handle composite keys, otherwise we would just use `self.class.primary_key.to_sym => self.id`. self.class.delete_all!(Hash[[Array(self.class.primary_key), Array(self.id)].transpose]) if persisted? self.paranoid_value = self.class.delete_now_value @@ -181,10 +181,8 @@ def destroy_dependent_associations! self.class.dependent_associations.each do |reflection| next unless (klass = get_reflection_class(reflection)).paranoid? - scope = klass.only_deleted - # Merge in the association's scope - scope = scope.merge(association(reflection.name).association_scope) + scope = association(reflection.name).association_scope scope.each do |object| object.destroy! From 5932cfe2ee05cb23674d778eb98d82502814c365 Mon Sep 17 00:00:00 2001 From: pavlos Date: Thu, 11 Jun 2015 14:41:52 -0700 Subject: [PATCH 091/105] destroy_dependent_associations! calls destroy_fully! --- lib/acts_as_paranoid/core.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 507d29b..3525ce8 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -185,7 +185,7 @@ def destroy_dependent_associations! scope = association(reflection.name).association_scope scope.each do |object| - object.destroy! + object.destroy_fully! end end end From c3a41d5b52623ebfff30a50ab886d6db8559bc5e Mon Sep 17 00:00:00 2001 From: Sergey Petrenko Date: Mon, 22 Feb 2016 11:17:41 -0800 Subject: [PATCH 092/105] comply to pavlos --- lib/acts_as_paranoid/core.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 0ed73cd..3525ce8 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -146,6 +146,7 @@ def recover(options={}) paranoid_original_value = self.paranoid_value self.paranoid_value = nil self.save! + recover_dependent_associations(paranoid_original_value, options[:recovery_window], options) if options[:recursive] end end @@ -163,7 +164,7 @@ def recover_dependent_associations(paranoid_original_value, window, options) # We can only recover by window if both parent and dependant have a # paranoid column type of :time. if self.class.paranoid_column_type == :time && klass.paranoid_column_type == :time - scope = scope.merge(reflection.klass.deleted_inside_time_window(paranoid_original_value, window)) + scope = scope.deleted_inside_time_window(paranoid_original_value, window) end unless reflection.options[:dependent] == :delete_all From 5fdff4ddc8c27cc6772256a930a43150470e5cd0 Mon Sep 17 00:00:00 2001 From: Sukrutha Krishnegowda Date: Thu, 26 Jan 2017 11:09:17 -0800 Subject: [PATCH 093/105] Adding new soft_delete callback --- lib/acts_as_paranoid/core.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 3525ce8..2855d5b 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -7,6 +7,7 @@ def self.included(base) module ClassMethods def self.extended(base) base.define_callbacks :recover, terminator: lambda { |target, result| result == false } + base.define_callbacks :soft_destroy, terminator: lambda { |target, result| result == false } end def before_recover(method) @@ -17,6 +18,14 @@ def after_recover(method) set_callback :recover, :after, method end + def before_soft_destroy(method) + set_callback :soft_destroy, :before, method + end + + def after_soft_destroy(method) + set_callback :soft_destroy, :after, method + end + def with_deleted without_paranoid_default_scope end @@ -114,9 +123,11 @@ def destroy! unless deleted? with_transaction_returning_status do if self.class.paranoid_configuration[:dependent_destroy_paranoid_only] - destroy_paranoid_associations - self.paranoid_value = self.class.delete_now_value - self.save! + run_callbacks :soft_destroy do + destroy_paranoid_associations + self.paranoid_value = self.class.delete_now_value + self.save! + end else run_callbacks :destroy do # Handle composite keys, otherwise we would just use `self.class.primary_key.to_sym => self.id`. From 8d3e7e5ed5ddc55c54d18a89fea444aa2080a05e Mon Sep 17 00:00:00 2001 From: Sukrutha Krishnegowda Date: Fri, 27 Jan 2017 10:27:26 -0800 Subject: [PATCH 094/105] README.md changes --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index bd04f6b..9590a73 100755 --- a/README.md +++ b/README.md @@ -208,6 +208,32 @@ child.parent #=> nil child.parent_including_deleted #=> Parent (it works!) ``` +### Creating Custom Callbacks + +Define custom callbacks in lib/acts_as_paranoid/core.rb. Depending on the :after , :before callbacks required, use set_callbacks as shown below. + +```ruby +def self.extended(base) + base.define_callbacks :soft_destroy, terminator: lambda { |target, result| result == false } +end + +def before_soft_destroy(method) + set_callback :soft_destroy, :before, method +end + +def after_soft_destroy(method) + set_callback :soft_destroy, :after, method +end +``` +usage in acts_as_paranoid class +```ruby +before_soft_destroy :peform_before_soft_destroy +after_soft_destroy :peform_after_soft__destroy +``` +### Custom callbacks +- `before_soft_destroy` : This is executed before soft_destroy happens +- `before_soft_destroy` : This is executed after marking the record to be soft destroyed + ## Caveats Watch out for these caveats: From 7865bae693666e6b414f1edabd9fa4b3a7d917c6 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Sat, 4 Feb 2017 22:38:47 -0800 Subject: [PATCH 095/105] Adding scoping to dependent relationships --- lib/acts_as_paranoid/core.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 2855d5b..1f3a878 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -205,7 +205,7 @@ def destroy_paranoid_associations self.class.dependent_associations.each do |reflection| if reflection.klass.paranoid? dependent_type = reflection.options[:dependent] - association_scope = association(reflection.name).association_scope + association_scope = association(reflection.name).association_scope.where(self.class.paranoid_column => nil) if dependent_type == :destroy association_scope.each do |object| object.send(reflection.options[:dependent]) From a4386f66c553db4e9d7a698af70f094c761e5772 Mon Sep 17 00:00:00 2001 From: Matthew Seal Date: Tue, 25 Apr 2017 18:40:30 -0700 Subject: [PATCH 096/105] Added without_default_scope option --- README.md | 16 +++++++++++++++- lib/acts_as_paranoid.rb | 11 +++++++++-- test/test_core.rb | 8 ++++---- test/test_default_scopes.rb | 17 ++++++++++++----- test/test_helper.rb | 14 +++++++++++--- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9590a73..d6d7ce2 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ActsAsParanoid -[![Build Status](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid.png?branch=master)](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid) +[![Build Status](https://travis-ci.org/OpenGov/acts_as_paranoid.png?branch=opengov-master)](https://travis-ci.org/OpenGov/acts_as_paranoid) A Rails plugin to add soft delete. @@ -245,6 +245,20 @@ Watch out for these caveats: - `unscoped` will return all records, deleted or not - Assignment of `self.table_name` in a model must come before `acts_as_paranoid` or you will get SQL errors. +# Specs +To run specs for this repository, first get bundler and install dependencies +``` +bundle install +``` + +If it complains about sqlite3 you may need to install the sqlite3 headers. Using `gem install sqlite3` should suggest how to do this. + +``` +bundle exec rake test +``` + +And all the specs should be green. + # Acknowledgements * To [Rick Olson](https://github.com/technoweenie) for creating acts_as_paranoid diff --git a/lib/acts_as_paranoid.rb b/lib/acts_as_paranoid.rb index 0a9a49b..59d444c 100644 --- a/lib/acts_as_paranoid.rb +++ b/lib/acts_as_paranoid.rb @@ -18,7 +18,14 @@ def acts_as_paranoid(options = {}) class_attribute :paranoid_configuration, :paranoid_column_reference - self.paranoid_configuration = { :column => "deleted_at", :column_type => "time", :recover_dependent_associations => true, :dependent_recovery_window => 2.minutes, :dependent_destroy_paranoid_only => false } + self.paranoid_configuration = { + column: "deleted_at", + column_type: "time", + recover_dependent_associations: true, + dependent_recovery_window: 2.minutes, + dependent_destroy_paranoid_only: false, + without_default_scope: false + } self.paranoid_configuration.merge!({ :deleted_value => "deleted" }) if options[:column_type] == "string" self.paranoid_configuration.merge!(options) # user options @@ -31,7 +38,7 @@ def acts_as_paranoid(options = {}) include ActsAsParanoid::Core # Magic! - default_scope { where(paranoid_default_scope_sql) } + default_scope { where(paranoid_default_scope_sql) } unless paranoid_configuration[:without_default_scope] if paranoid_configuration[:column_type] == 'time' scope :deleted_inside_time_window, lambda {|time, window| diff --git a/test/test_core.rb b/test/test_core.rb index cc189b5..04b14da 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -209,17 +209,17 @@ def test_recursive_recovery_dependant_window def test_recursive_recovery_for_belongs_to_polymorphic child_1 = ParanoidAndroid.create - section_1 = ParanoidSection.create(:paranoid_thing => child_1) + section_1 = ParanoidSection.create(paranoid_thing: child_1) - child_2 = ParanoidHuman.create(:gender => 'male') - section_2 = ParanoidSection.create(:paranoid_thing => child_2) + child_2 = ParanoidHuman.create(alien: false) + section_2 = ParanoidSection.create(paranoid_thing: child_2) assert_equal section_1.paranoid_thing, child_1 assert_equal section_1.paranoid_thing.class, ParanoidAndroid assert_equal section_2.paranoid_thing, child_2 assert_equal section_2.paranoid_thing.class, ParanoidHuman - parent = ParanoidTime.create(:name => "paranoid_parent") + parent = ParanoidTime.create(name: "paranoid_parent") parent.paranoid_sections << section_1 parent.paranoid_sections << section_2 diff --git a/test/test_default_scopes.rb b/test/test_default_scopes.rb index 330ad93..80bb079 100644 --- a/test/test_default_scopes.rb +++ b/test/test_default_scopes.rb @@ -4,12 +4,14 @@ class MultipleDefaultScopesTest < ParanoidBaseTest def setup setup_db - # Naturally, the default scope for humans is male. Sexism++ - ParanoidHuman.create! :gender => 'male' - ParanoidHuman.create! :gender => 'male' - ParanoidHuman.create! :gender => 'male' - ParanoidHuman.create! :gender => 'female' + ParanoidHuman.create! alien: false + ParanoidHuman.create! alien: false + ParanoidHuman.create! alien: false + # We're worried about bob... + ParanoidHuman.create! alien: true + end + def test_basic_scope assert_equal 3, ParanoidHuman.count assert_equal 4, ParanoidHuman.unscoped.count end @@ -49,4 +51,9 @@ def test_real_removal_with_multiple_default_scope assert_equal 0, ParanoidHuman.only_deleted.count assert_equal 1, ParanoidHuman.unscoped.count end + + def test_no_default_scope + assert_equal 4, LessParanoidHuman.count + assert_equal 4, LessParanoidHuman.unscoped.count + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 7f968ab..d831dae 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,4 +1,6 @@ require 'bundler' +# Need this import first or specs can't run +require 'active_record' begin Bundler.require(:default, :development) rescue Bundler::BundlerError => e @@ -164,8 +166,8 @@ def setup_db timestamps t end - create_table :paranoid_humen do |t| - t.string :gender + create_table :paranoid_humans do |t| + t.boolean :alien t.datetime :deleted_at timestamps t @@ -408,8 +410,14 @@ class ParanoidTree < ActiveRecord::Base end class ParanoidHuman < ActiveRecord::Base + self.table_name = "paranoid_humans" acts_as_paranoid - default_scope { where('gender = ?', 'male') } + default_scope { where('alien = ?', false) } +end + +class LessParanoidHuman < ActiveRecord::Base + self.table_name = "paranoid_humans" + acts_as_paranoid without_default_scope: true end class ParanoidAndroid < ActiveRecord::Base From 656fd280bb6c7d53337dc0a935f79de40a74c673 Mon Sep 17 00:00:00 2001 From: Matthew Seal Date: Wed, 26 Apr 2017 00:04:22 -0700 Subject: [PATCH 097/105] Added without_deleted. Allowed for symbol options. Added more test coverage, --- lib/acts_as_paranoid.rb | 8 ++-- lib/acts_as_paranoid/core.rb | 28 +++++++++---- test/test_core.rb | 79 ++++++++++++++++++++++++++++++++++-- test/test_helper.rb | 34 +++++++++++++++- 4 files changed, 132 insertions(+), 17 deletions(-) diff --git a/lib/acts_as_paranoid.rb b/lib/acts_as_paranoid.rb index 59d444c..7541c45 100644 --- a/lib/acts_as_paranoid.rb +++ b/lib/acts_as_paranoid.rb @@ -26,10 +26,12 @@ def acts_as_paranoid(options = {}) dependent_destroy_paranoid_only: false, without_default_scope: false } - self.paranoid_configuration.merge!({ :deleted_value => "deleted" }) if options[:column_type] == "string" + self.paranoid_configuration[:deleted_value] = "deleted" if options[:column_type].to_s == "string" self.paranoid_configuration.merge!(options) # user options - raise ArgumentError, "'time', 'boolean' or 'string' expected for :column_type option, got #{paranoid_configuration[:column_type]}" unless ['time', 'boolean', 'string'].include? paranoid_configuration[:column_type] + unless ['time', 'boolean', 'string'].include? paranoid_configuration[:column_type].to_s + raise ArgumentError, "'time', 'boolean' or 'string' expected for :column_type option, got #{paranoid_configuration[:column_type]}" + end self.paranoid_column_reference = "#{self.table_name}.#{paranoid_configuration[:column]}" @@ -40,7 +42,7 @@ def acts_as_paranoid(options = {}) # Magic! default_scope { where(paranoid_default_scope_sql) } unless paranoid_configuration[:without_default_scope] - if paranoid_configuration[:column_type] == 'time' + if paranoid_configuration[:column_type].to_s == 'time' scope :deleted_inside_time_window, lambda {|time, window| deleted_after_time((time - window)).deleted_before_time((time + window)) } diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 1f3a878..831c9af 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -30,6 +30,10 @@ def with_deleted without_paranoid_default_scope end + def without_deleted + with_paranoid_default_scope + end + def only_deleted if string_type_with_deleted_value? without_paranoid_default_scope.where("#{paranoid_column_reference} IS ?", paranoid_configuration[:deleted_value]) @@ -49,7 +53,7 @@ def delete_all(conditions = nil) def paranoid_default_scope_sql if string_type_with_deleted_value? self.all.table[paranoid_column].eq(nil). - or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value])). + or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value].to_s)). to_sql else self.all.table[paranoid_column].eq(nil).to_sql @@ -73,13 +77,13 @@ def dependent_associations end def delete_now_value - case paranoid_configuration[:column_type] - when "time" + case paranoid_column_type + when :time Time.now - when "boolean" + when :boolean true - when "string" - paranoid_configuration[:deleted_value] + when :string + paranoid_configuration[:deleted_value].to_s end end @@ -90,9 +94,15 @@ def without_paranoid_default_scope if scope.where_values.include? paranoid_default_scope_sql # ActiveRecord 4.1 scope.where_values.delete(paranoid_default_scope_sql) - else - scope = scope.with_default_scope - scope.where_values.delete(paranoid_default_scope_sql) + end + + scope + end + + def with_paranoid_default_scope + scope = self.all + unless scope.where_values.include? paranoid_default_scope_sql + scope = scope.where(paranoid_default_scope_sql) end scope diff --git a/test/test_core.rb b/test/test_core.rb index 04b14da..5a602b2 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -29,29 +29,63 @@ def test_fake_removal ParanoidBoolean.delete_all("name = 'paranoid' OR name = 'really paranoid'") ParanoidString.first.destroy assert_equal 2, ParanoidTime.count + assert_equal 3, LessParanoidTime.count assert_equal 1, ParanoidBoolean.count + assert_equal 3, LessParanoidBoolean.count assert_equal 0, ParanoidString.count - assert_equal 1, ParanoidTime.only_deleted.count - assert_equal 2, ParanoidBoolean.only_deleted.count - assert_equal 1, ParanoidString.only_deleted.count + assert_equal 1, LessParanoidString.count assert_equal 3, ParanoidTime.with_deleted.count + assert_equal 3, LessParanoidTime.with_deleted.count assert_equal 3, ParanoidBoolean.with_deleted.count + assert_equal 3, LessParanoidBoolean.with_deleted.count assert_equal 1, ParanoidString.with_deleted.count + assert_equal 1, LessParanoidString.with_deleted.count + assert_equal 2, ParanoidTime.without_deleted.count + assert_equal 2, LessParanoidTime.without_deleted.count + assert_equal 1, ParanoidBoolean.without_deleted.count + assert_equal 1, LessParanoidBoolean.without_deleted.count + assert_equal 0, ParanoidString.without_deleted.count + assert_equal 0, LessParanoidString.without_deleted.count + assert_equal 1, ParanoidTime.only_deleted.count + assert_equal 1, LessParanoidTime.only_deleted.count + assert_equal 2, ParanoidBoolean.only_deleted.count + assert_equal 2, LessParanoidBoolean.only_deleted.count + assert_equal 1, ParanoidString.only_deleted.count + assert_equal 1, LessParanoidString.only_deleted.count end def test_real_removal + assert_equal 3, ParanoidTime.count + assert_equal 3, ParanoidBoolean.count + assert_equal 1, ParanoidString.count + ParanoidTime.first.destroy_fully! ParanoidBoolean.delete_all!("name = 'extremely paranoid' OR name = 'really paranoid'") ParanoidString.first.destroy_fully! assert_equal 2, ParanoidTime.count + assert_equal 2, LessParanoidTime.count assert_equal 1, ParanoidBoolean.count + assert_equal 1, LessParanoidBoolean.count assert_equal 0, ParanoidString.count + assert_equal 0, LessParanoidString.count assert_equal 2, ParanoidTime.with_deleted.count + assert_equal 2, LessParanoidTime.with_deleted.count assert_equal 1, ParanoidBoolean.with_deleted.count + assert_equal 1, LessParanoidBoolean.with_deleted.count assert_equal 0, ParanoidString.with_deleted.count + assert_equal 0, LessParanoidString.with_deleted.count + assert_equal 2, ParanoidTime.without_deleted.count + assert_equal 2, LessParanoidTime.without_deleted.count + assert_equal 1, ParanoidBoolean.without_deleted.count + assert_equal 1, LessParanoidBoolean.without_deleted.count + assert_equal 0, ParanoidString.without_deleted.count + assert_equal 0, LessParanoidString.without_deleted.count assert_equal 0, ParanoidTime.only_deleted.count + assert_equal 0, LessParanoidTime.only_deleted.count assert_equal 0, ParanoidBoolean.only_deleted.count + assert_equal 0, LessParanoidBoolean.only_deleted.count assert_equal 0, ParanoidString.only_deleted.count + assert_equal 0, LessParanoidString.only_deleted.count ParanoidTime.first.destroy ParanoidTime.only_deleted.first.destroy @@ -360,37 +394,76 @@ def test_string_type_with_no_nil_value_before_destroy assert_equal 1, ParanoidString.where(:id => ps).count end + def test_string_type_with_no_nil_value_before_destroy_without_scope + ps = LessParanoidString.create!(:deleted => 'not dead') + assert_equal 1, LessParanoidString.where(:id => ps).count + end + def test_string_type_with_no_nil_value_after_destroy ps = ParanoidString.create!(:deleted => 'not dead') ps.destroy assert_equal 0, ParanoidString.where(:id => ps).count end + def test_string_type_with_no_nil_value_after_destroy_without_scope + ps = LessParanoidString.create!(:deleted => 'not dead') + ps.destroy + assert_equal 1, LessParanoidString.where(:id => ps).count + end + def test_string_type_with_no_nil_value_before_destroy_with_deleted ps = ParanoidString.create!(:deleted => 'not dead') assert_equal 1, ParanoidString.with_deleted.where(:id => ps).count end + def test_string_type_with_no_nil_value_before_destroy_without_scope + ps = LessParanoidString.create!(:deleted => 'not dead') + assert_equal 1, LessParanoidString.with_deleted.where(:id => ps).count + end + def test_string_type_with_no_nil_value_after_destroy_with_deleted ps = ParanoidString.create!(:deleted => 'not dead') ps.destroy assert_equal 1, ParanoidString.with_deleted.where(:id => ps).count end + def test_string_type_with_no_nil_value_after_destroy_with_deleted_without_scope + ps = LessParanoidString.create!(:deleted => 'not dead') + ps.destroy + assert_equal 1, LessParanoidString.with_deleted.where(:id => ps).count + end + def test_string_type_with_no_nil_value_before_destroy_only_deleted ps = ParanoidString.create!(:deleted => 'not dead') assert_equal 0, ParanoidString.only_deleted.where(:id => ps).count end + def test_string_type_with_no_nil_value_before_destroy_only_deleted_without_scope + ps = LessParanoidString.create!(:deleted => 'not dead') + assert_equal 0, LessParanoidString.only_deleted.where(:id => ps).count + end + def test_string_type_with_no_nil_value_after_destroy_only_deleted ps = ParanoidString.create!(:deleted => 'not dead') ps.destroy assert_equal 1, ParanoidString.only_deleted.where(:id => ps).count end + def test_string_type_with_no_nil_value_after_destroy_only_deleted_without_scope + ps = LessParanoidString.create!(:deleted => 'not dead') + ps.destroy + assert_equal 1, LessParanoidString.only_deleted.where(:id => ps).count + end + def test_string_type_with_no_nil_value_after_destroyed_twice ps = ParanoidString.create!(:deleted => 'not dead') 2.times { ps.destroy } assert_equal 0, ParanoidString.with_deleted.where(:id => ps).count end + + def test_string_type_with_no_nil_value_after_destroyed_twice_without_scope + ps = LessParanoidString.create!(:deleted => 'not dead') + 2.times { ps.destroy } + assert_equal 0, LessParanoidString.with_deleted.where(:id => ps).count + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index d831dae..20f486e 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -212,8 +212,33 @@ class ParanoidTime < ActiveRecord::Base belongs_to :not_paranoid, :dependent => :destroy end +class LessParanoidTime < ActiveRecord::Base + self.table_name = "paranoid_times" + acts_as_paranoid without_default_scope: true + validates_uniqueness_of :name + + has_many :paranoid_has_many_dependants, :dependent => :destroy + has_many :paranoid_booleans, :dependent => :destroy + has_many :not_paranoids, :dependent => :delete_all + has_many :paranoid_sections, :dependent => :destroy + + has_one :has_one_not_paranoid, :dependent => :destroy + + belongs_to :not_paranoid, :dependent => :destroy +end + class ParanoidBoolean < ActiveRecord::Base - acts_as_paranoid :column_type => "boolean", :column => "is_deleted" + acts_as_paranoid column_type: "boolean", column: "is_deleted" + validates_as_paranoid + validates_uniqueness_of_without_deleted :name + + belongs_to :paranoid_time + has_one :paranoid_has_one_dependant, :dependent => :destroy +end + +class LessParanoidBoolean < ActiveRecord::Base + self.table_name = "paranoid_booleans" + acts_as_paranoid column_type: "boolean", column: "is_deleted", without_default_scope: true validates_as_paranoid validates_uniqueness_of_without_deleted :name @@ -222,7 +247,12 @@ class ParanoidBoolean < ActiveRecord::Base end class ParanoidString < ActiveRecord::Base - acts_as_paranoid :column_type => "string", :column => "deleted", :deleted_value => "dead" + acts_as_paranoid column_type: :string, column: :deleted, deleted_value: :dead +end + +class LessParanoidString < ActiveRecord::Base + self.table_name = "paranoid_strings" + acts_as_paranoid column_type: :string, column: :deleted, deleted_value: :dead, without_default_scope: true end class NotParanoid < ActiveRecord::Base From b8716235b94255481ca7fc1d83cc60b7e8334e25 Mon Sep 17 00:00:00 2001 From: Matthew Seal Date: Wed, 26 Apr 2017 00:30:23 -0700 Subject: [PATCH 098/105] Added more scope tests --- test/test_default_scopes.rb | 52 ++++++++++++++++++++++++++++++++++--- test/test_helper.rb | 1 + 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/test/test_default_scopes.rb b/test/test_default_scopes.rb index 80bb079..ea1dff6 100644 --- a/test/test_default_scopes.rb +++ b/test/test_default_scopes.rb @@ -20,40 +20,86 @@ def test_fake_removal_with_multiple_default_scope ParanoidHuman.first.destroy assert_equal 2, ParanoidHuman.count assert_equal 3, ParanoidHuman.with_deleted.count + assert_equal 2, ParanoidHuman.without_deleted.count assert_equal 1, ParanoidHuman.only_deleted.count assert_equal 4, ParanoidHuman.unscoped.count ParanoidHuman.destroy_all assert_equal 0, ParanoidHuman.count assert_equal 3, ParanoidHuman.with_deleted.count - assert_equal 3, ParanoidHuman.with_deleted.count + assert_equal 0, ParanoidHuman.without_deleted.count + assert_equal 3, ParanoidHuman.only_deleted.count assert_equal 4, ParanoidHuman.unscoped.count end + def test_fake_removal_with_no_paranoid_default_scope + LessParanoidHuman.first.destroy + assert_equal 3, LessParanoidHuman.count + assert_equal 3, LessParanoidHuman.with_deleted.count + assert_equal 2, LessParanoidHuman.without_deleted.count + assert_equal 1, LessParanoidHuman.only_deleted.count + assert_equal 4, LessParanoidHuman.unscoped.count + + LessParanoidHuman.without_deleted.destroy_all + assert_equal 3, LessParanoidHuman.count + assert_equal 3, LessParanoidHuman.with_deleted.count + assert_equal 0, LessParanoidHuman.without_deleted.count + assert_equal 3, LessParanoidHuman.only_deleted.count + assert_equal 4, LessParanoidHuman.unscoped.count + end + def test_real_removal_with_multiple_default_scope # two-step ParanoidHuman.first.destroy ParanoidHuman.only_deleted.first.destroy assert_equal 2, ParanoidHuman.count assert_equal 2, ParanoidHuman.with_deleted.count + assert_equal 2, ParanoidHuman.without_deleted.count assert_equal 0, ParanoidHuman.only_deleted.count assert_equal 3, ParanoidHuman.unscoped.count ParanoidHuman.first.destroy_fully! assert_equal 1, ParanoidHuman.count assert_equal 1, ParanoidHuman.with_deleted.count + assert_equal 1, ParanoidHuman.without_deleted.count assert_equal 0, ParanoidHuman.only_deleted.count assert_equal 2, ParanoidHuman.unscoped.count ParanoidHuman.delete_all! assert_equal 0, ParanoidHuman.count assert_equal 0, ParanoidHuman.with_deleted.count + assert_equal 0, ParanoidHuman.without_deleted.count assert_equal 0, ParanoidHuman.only_deleted.count assert_equal 1, ParanoidHuman.unscoped.count end - def test_no_default_scope - assert_equal 4, LessParanoidHuman.count + def test_real_removal_with_no_paranoid_default_scope + # two-step + LessParanoidHuman.first.destroy + LessParanoidHuman.only_deleted.first.destroy + assert_equal 2, LessParanoidHuman.count + assert_equal 2, LessParanoidHuman.with_deleted.count + assert_equal 2, LessParanoidHuman.without_deleted.count + assert_equal 0, LessParanoidHuman.only_deleted.count + assert_equal 3, LessParanoidHuman.unscoped.count + + LessParanoidHuman.first.destroy_fully! + assert_equal 1, LessParanoidHuman.count + assert_equal 1, LessParanoidHuman.with_deleted.count + assert_equal 1, LessParanoidHuman.without_deleted.count + assert_equal 0, LessParanoidHuman.only_deleted.count + assert_equal 2, LessParanoidHuman.unscoped.count + + LessParanoidHuman.delete_all! + assert_equal 0, LessParanoidHuman.count + assert_equal 0, LessParanoidHuman.with_deleted.count + assert_equal 0, LessParanoidHuman.without_deleted.count + assert_equal 0, LessParanoidHuman.only_deleted.count + assert_equal 1, LessParanoidHuman.unscoped.count + end + + def test_no_paranoid_default_scope + assert_equal 3, LessParanoidHuman.count assert_equal 4, LessParanoidHuman.unscoped.count end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 20f486e..7415f63 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -448,6 +448,7 @@ class ParanoidHuman < ActiveRecord::Base class LessParanoidHuman < ActiveRecord::Base self.table_name = "paranoid_humans" acts_as_paranoid without_default_scope: true + default_scope { where('alien = ?', false) } end class ParanoidAndroid < ActiveRecord::Base From 5d05feda8ee213d8483cc3edaa2f6b88ee9bea1a Mon Sep 17 00:00:00 2001 From: Matthew Seal Date: Wed, 10 May 2017 17:59:39 -0700 Subject: [PATCH 099/105] Removed composite key support (no specs). Consolidated some repeated code. Updated specs and builds to work better. --- .travis.yml | 4 +++ Gemfile | 4 +++ lib/acts_as_paranoid/core.rb | 54 ++++++++++++++++++------------------ test/test_associations.rb | 8 +++--- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/.travis.yml b/.travis.yml index d7c19ba..5a7aefd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,13 @@ language: ruby script: "bundle exec rake test" +sudo: required rvm: - 1.9.3 - 2.0.0 - 2.1 - ruby-head - jruby + - jruby-9.1.7.0 - rbx gemfile: - gemfiles/active_record_40.gemfile @@ -14,8 +16,10 @@ gemfile: - gemfiles/active_record_edge.gemfile matrix: allow_failures: + - rvm: 1.9.3 - rvm: ruby-head - rvm: rbx - rvm: jruby + - gemfile: gemfiles/active_record_40.gemfile - gemfile: gemfiles/active_record_edge.gemfile fast_finish: true diff --git a/Gemfile b/Gemfile index a1a1fbf..80024bb 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,9 @@ source "https://rubygems.org" +# Older bundler has a known error which prevents bundle install on ruby 1.9 +gem "bundler", ">=1.12.0" + + # Development dependencies group :development do gem "sqlite3", :platforms => [:ruby] diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 831c9af..7e6c72c 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -121,8 +121,8 @@ def destroy_fully! with_transaction_returning_status do destroy_dependent_associations! run_callbacks :destroy do - # Handle composite keys, otherwise we would just use `self.class.primary_key.to_sym => self.id`. - self.class.delete_all!(Hash[[Array(self.class.primary_key), Array(self.id)].transpose]) if persisted? + # We need to use delete_all! here because we overwrite everything else to not actually delete + self.class.delete_all!(id: self.id) if persisted? self.paranoid_value = self.class.delete_now_value freeze end @@ -140,8 +140,8 @@ def destroy! end else run_callbacks :destroy do - # Handle composite keys, otherwise we would just use `self.class.primary_key.to_sym => self.id`. - self.class.delete_all(Hash[[Array(self.class.primary_key), Array(self.id)].transpose]) if persisted? + # We need to use delete_all here because we overwrite everything else to not actually delete + self.class.delete_all(id: self.id) if persisted? self.paranoid_value = self.class.delete_now_value self end @@ -199,32 +199,11 @@ def recover_dependent_associations(paranoid_original_value, window, options) end def destroy_dependent_associations! - self.class.dependent_associations.each do |reflection| - next unless (klass = get_reflection_class(reflection)).paranoid? - - # Merge in the association's scope - scope = association(reflection.name).association_scope - - scope.each do |object| - object.destroy_fully! - end - end + paranoid_associations_typed_destroy(:destroy_fully!) end def destroy_paranoid_associations - self.class.dependent_associations.each do |reflection| - if reflection.klass.paranoid? - dependent_type = reflection.options[:dependent] - association_scope = association(reflection.name).association_scope.where(self.class.paranoid_column => nil) - if dependent_type == :destroy - association_scope.each do |object| - object.send(reflection.options[:dependent]) - end - elsif dependent_type == :delete_all - association_scope.delete_all - end - end - end + paranoid_associations_typed_destroy(:destroy) end def deleted? @@ -247,5 +226,26 @@ def get_reflection_class(reflection) def paranoid_value=(value) self.send("#{self.class.paranoid_column}=", value) end + + + def paranoid_associations_typed_destroy(destroy_type = nil) + self.class.dependent_associations.each do |reflection| + klass = get_reflection_class(reflection) + next unless klass.paranoid? + + dependent_type = reflection.options[:dependent] + # Merge in the association's scope + association_scope = association(reflection.name).association_scope + if dependent_type == :destroy + destroy_type = :destroy if destroy_type.nil? + unless destroy_type.to_sym == :destroy_fully! + association_scope = association_scope.where(klass.paranoid_column => nil) + end + association_scope.each { |object| object.send(destroy_type) } + elsif dependent_type == :delete_all + association_scope.delete_all! + end + end + end end end diff --git a/test/test_associations.rb b/test/test_associations.rb index 55b0a79..f02495c 100644 --- a/test/test_associations.rb +++ b/test/test_associations.rb @@ -2,10 +2,10 @@ class AssociationsTest < ParanoidBaseTest def test_removal_with_associations - paranoid_company_1 = ParanoidDestroyCompany.create! :name => "ParanoidDestroyCompany #1" - paranoid_company_2 = ParanoidDeleteCompany.create! :name => "ParanoidDestroyCompany #1" - paranoid_company_1.paranoid_products.create! :name => "ParanoidProduct #1" - paranoid_company_2.paranoid_products.create! :name => "ParanoidProduct #2" + paranoid_company_1 = ParanoidDestroyCompany.create!(name: "ParanoidDestroyCompany #1") + paranoid_company_2 = ParanoidDeleteCompany.create!(name: "ParanoidDeleteCompany #2") + paranoid_company_1.paranoid_products.create!(name: "ParanoidProduct #1") + paranoid_company_2.paranoid_products.create!(name: "ParanoidProduct #2") assert_equal 1, ParanoidDestroyCompany.count assert_equal 1, ParanoidDeleteCompany.count From 7a0918e8051f2a5bb5c486e6b33c2574e82e34f7 Mon Sep 17 00:00:00 2001 From: Matthew Seal Date: Wed, 10 May 2017 18:24:15 -0700 Subject: [PATCH 100/105] Added 1.9.3 and jruby to passing builds --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5a7aefd..6df3186 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,8 @@ gemfile: - gemfiles/active_record_edge.gemfile matrix: allow_failures: - - rvm: 1.9.3 - rvm: ruby-head - rvm: rbx - - rvm: jruby - gemfile: gemfiles/active_record_40.gemfile - gemfile: gemfiles/active_record_edge.gemfile fast_finish: true From ee635a12be71bf347640da5006cac8520648a075 Mon Sep 17 00:00:00 2001 From: Robert Hromej Date: Fri, 30 Jul 2021 17:46:10 +0300 Subject: [PATCH 101/105] [PLTF-693] Upgrade to V0.5.0.rc1 (#7) * Update readme.md foreign_key => :parent_id TO :foreign_key => :parent_id * When recovering associated records, need to specify the table name when querying the recovery window. Otherwise, an 'ambiguous column' error is thrown * Thanks @mvz <3 * Execute tests on Ruby 2.2 as well * Update rails 4.2 to latest release for CI * Remove edge tests since Rails 5 is unsupported at this time * Bump version * ActiveRecord queries with includes now respect :with_deleted => true * Update core.rb Is better to use alias method instead of defining delegator methods. * Remove legacy observer reference * Add test for decrement counters * Manually decrement counters with activerecord >= 4.2 * Compatibility with Rails 5 * Running tests for Rails 5 with compatible versions of ruby * Fix typo * fix Default scope * Get working bundler before running tests Also add Ruby 2.3 and Jruby 9k to matrix * Add patch-levels to rvm rubies for travis CI * Added support for allow_nulls option for boolean column. * :scissors: * Clarify supported versions of Rails * Thank you @sjke for working on Rails 5 support * Some doc cleanups :nail_care: * Revert "Merge pull request #40 from paveldruzyak/master" This reverts commit 8df82c4af50725282a7b66bdb36dc2ae3ddcbe55, reversing changes made to 64bfe2f5af46c0344cb4d6b71e7cd0cc9775855f. * Document destroy_fully! Closes #51 See also 3c12279 * :nail_care: * Bump to first release candidate Co-authored-by: Jenya Zueva Co-authored-by: Cosmin A Co-authored-by: Zachary Scott Co-authored-by: Zachary Scott Co-authored-by: Teemu Kupari Co-authored-by: Ehsan Yousefi Co-authored-by: Matt Co-authored-by: Pavel Druziak Co-authored-by: Andrey Ponomarenko Co-authored-by: fmnoise@gmail.com Co-authored-by: Nu-hin --- .travis.yml | 22 ++++- README.md | 58 +++++++++---- Rakefile | 8 +- acts_as_paranoid.gemspec | 4 +- gemfiles/active_record_42.gemfile | 4 +- ..._edge.gemfile => active_record_50.gemfile} | 8 +- lib/acts_as_paranoid.rb | 13 ++- lib/acts_as_paranoid/core.rb | 52 ++++++++---- lib/acts_as_paranoid/preloader_association.rb | 15 ++++ lib/acts_as_paranoid/validations.rb | 84 +++++++++++++------ lib/acts_as_paranoid/version.rb | 2 +- test/test_core.rb | 44 +++++++++- test/test_helper.rb | 57 ++++++++++++- test/test_preloader_association.rb | 27 ++++++ 14 files changed, 311 insertions(+), 87 deletions(-) rename gemfiles/{active_record_edge.gemfile => active_record_50.gemfile} (65%) create mode 100644 lib/acts_as_paranoid/preloader_association.rb create mode 100644 test/test_preloader_association.rb diff --git a/.travis.yml b/.travis.yml index 6df3186..d3555e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,23 +1,39 @@ language: ruby + +before_install: + - rvm get head + - gem install bundler + script: "bundle exec rake test" sudo: required rvm: - 1.9.3 - 2.0.0 - - 2.1 + - 2.1.9 + - 2.2.5 + - 2.3.1 - ruby-head - jruby - - jruby-9.1.7.0 + - jruby-9.1.0.0 - rbx gemfile: - gemfiles/active_record_40.gemfile - gemfiles/active_record_41.gemfile - gemfiles/active_record_42.gemfile - - gemfiles/active_record_edge.gemfile + - gemfiles/active_record_50.gemfile matrix: allow_failures: - rvm: ruby-head - rvm: rbx - gemfile: gemfiles/active_record_40.gemfile - gemfile: gemfiles/active_record_edge.gemfile + - rvm: jruby + - rvm: jruby-9.1.0.0 fast_finish: true + exclude: + - rvm: 1.9.3 + gemfile: gemfiles/active_record_50.gemfile + - rvm: 2.0.0 + gemfile: gemfiles/active_record_50.gemfile + - rvm: 2.1.9 + gemfile: gemfiles/active_record_50.gemfile diff --git a/README.md b/README.md index d6d7ce2..eaede6b 100755 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ This gem can be used to hide records instead of deleting them, making them recov ## Support -**This branch targets Rails 4.x.** +**This branch targets Rails 4.x. and 5.x** -If you're working with another version, switch to the corresponding branch, or require an older version of the acts_as_paranoid gem. +If you're working with another version, switch to the corresponding branch, or require an older version of the `acts_as_paranoid` gem. ## Usage @@ -37,12 +37,18 @@ The values shown are the defaults. While *column* can be anything (as long as it If your column type is a `string`, you can also specify which value to use when marking an object as deleted by passing `:deleted_value` (default is "deleted"). Any records with a non-matching value in this column will be treated normally (ie: not deleted). +If your column type is a `boolean`, it is possible to specify `allow_nulls` option which is `true` by default. When set to `false`, entities that have `false` value in this column will be considered not deleted, and those which have `true` will be considered deleted. When `true` everything that has a not-null value will be considered deleted. + ### Filtering -If a record is deleted by ActsAsParanoid, it won't be retrieved when accessing the database. So, `Paranoiac.all` will **not** include the deleted_records. if you want to access them, you have 2 choices: +If a record is deleted by ActsAsParanoid, it won't be retrieved when accessing the database. + +So, `Paranoiac.all` will **not** include the **deleted records**. + +When you want to access them, you have 2 choices: ```ruby -Paranoiac.only_deleted # retrieves the deleted records +Paranoiac.only_deleted # retrieves only the deleted records Paranoiac.with_deleted # retrieves all records, deleted or not ``` @@ -67,7 +73,13 @@ paranoiac.destroy! Paranoiac.delete_all!(conditions) ``` -You can also permanently delete a record by calling `destroy` or `delete_all` on it **twice**. If a record was already deleted (hidden by ActsAsParanoid) and you delete it again, it will be removed from the database. Take this example: +You can also permanently delete a record by calling `destroy_fully!` on the object. + +Alternatively you can permanently delete a record by calling `destroy` or `delete_all` on the object **twice**. + +If a record was already deleted (hidden by `ActsAsParanoid`) and you delete it again, it will be removed from the database. + +Take this example: ```ruby p = Paranoiac.first @@ -83,7 +95,9 @@ Recovery is easy. Just invoke `recover` on it, like this: Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover ``` -All associations marked as `:dependent => :destroy` are also recursively recovered. If you would like to disable this behavior, you can call `recover` with the `recursive` option: +All associations marked as `:dependent => :destroy` are also recursively recovered. + +If you would like to disable this behavior, you can call `recover` with the `recursive` option: ```ruby Paranoiac.only_deleted.where("name = ?", "not dead yet").first.recover(:recursive => false) @@ -97,7 +111,13 @@ class Paranoiac < ActiveRecord::Base end ``` -By default, dependent records will be recovered if they were deleted within 2 minutes of the object upon which they depend. This restores the objects to the state before the recursive deletion without restoring other objects that were deleted earlier. The behavior is only available when both parent and dependant are using timestamp fields to mark deletion, which is the default behavior. This window can be changed with the `dependent_recovery_window` option: +By default, dependent records will be recovered if they were deleted within 2 minutes of the object upon which they depend. + +This restores the objects to the state before the recursive deletion without restoring other objects that were deleted earlier. + +The behavior is only available when both parent and dependant are using timestamp fields to mark deletion, which is the default behavior. + +This window can be changed with the `dependent_recovery_window` option: ```ruby class Paranoiac < ActiveRecord::Base @@ -125,9 +145,9 @@ ActiveRecord's built-in uniqueness validation does not account for records delet ```ruby class Paranoiac < ActiveRecord::Base - acts_as_paranoid - validates_as_paranoid - validates_uniqueness_of_without_deleted :name + acts_as_paranoid + validates_as_paranoid + validates_uniqueness_of_without_deleted :name end p1 = Paranoiac.create(:name => 'foo') @@ -150,13 +170,15 @@ Paranoiac.with_deleted.first.deleted? #=> true ### Scopes -As you've probably guessed, `with_deleted` and `only_deleted` are scopes. You can, however, chain them freely with other scopes you might have. This +As you've probably guessed, `with_deleted` and `only_deleted` are scopes. You can, however, chain them freely with other scopes you might have. + +For example: ```ruby Paranoiac.pretty.with_deleted ``` -is exactly the same as +This is exactly the same as: ```ruby Paranoiac.with_deleted.pretty @@ -166,8 +188,8 @@ You can work freely with scopes and it will just work: ```ruby class Paranoiac < ActiveRecord::Base - acts_as_paranoid - scope :pretty, where(:pretty => true) + acts_as_paranoid + scope :pretty, where(:pretty => true) end Paranoiac.create(:pretty => true) @@ -185,7 +207,9 @@ Paranoiac.pretty.only_deleted.count #=> 1 ### Associations -Associations are also supported. From the simplest behaviors you'd expect to more nifty things like the ones mentioned previously or the usage of the `:with_deleted` option with `belongs_to` +Associations are also supported. + +From the simplest behaviors you'd expect to more nifty things like the ones mentioned previously or the usage of the `:with_deleted` option with `belongs_to` ```ruby class Parent < ActiveRecord::Base @@ -197,7 +221,7 @@ class ParanoiacChild < ActiveRecord::Base belongs_to :parent # You may need to provide a foreign_key like this - belongs_to :parent_including_deleted, :class_name => "Parent", foreign_key => 'parent_id', :with_deleted => true + belongs_to :parent_including_deleted, :class_name => "Parent", :foreign_key => 'parent_id', :with_deleted => true end parent = Parent.first @@ -271,5 +295,7 @@ And all the specs should be green. * To [Charles G.](https://github.com/chuckg) for Rails 3.2 support and for making a desperately needed global code refactoring * To [Gonçalo Silva](https://github.com/goncalossilva) for supporting this gem prior to v0.4.3 * To [Jean Boussier](https://github.com/byroot) for initial Rails 4.0.0 support +* To [Matijs van Zuijlen](https://github.com/mvz) for Rails 4.1 and 4.2 support +* To [Andrey Ponomarenko](https://github.com/sjke) for Rails 5 support See `LICENSE`. diff --git a/Rakefile b/Rakefile index 47167de..da10630 100755 --- a/Rakefile +++ b/Rakefile @@ -9,18 +9,18 @@ desc 'Default: run unit tests.' task :default => "test:all" namespace :test do - %w(active_record_edge active_record_40 active_record_41 active_record_42).each do |version| + %w(active_record_40 active_record_41 active_record_42 active_record_50).each do |version| desc "Test acts_as_paranoid against #{version}" task version do - sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle --quiet" + sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle install --quiet" sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle exec rake -t test" end end desc "Run all tests for acts_as_paranoid" task :all do - %w(active_record_edge active_record_40 active_record_41 active_record_42).each do |version| - sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle --quiet" + %w(active_record_40 active_record_41 active_record_42 active_record_50).each do |version| + sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle install --quiet" sh "BUNDLE_GEMFILE='gemfiles/#{version}.gemfile' bundle exec rake -t test" end end diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 1a2f5b6..0bdb3f9 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -19,8 +19,8 @@ Gem::Specification.new do |spec| spec.required_rubygems_version = ">= 1.3.6" - spec.add_dependency "activerecord", "~> 4.0" - spec.add_dependency "activesupport", "~> 4.0" + spec.add_dependency "activerecord", ">= 4.0", "< 5.1" + spec.add_dependency "activesupport", ">= 4.0", "< 5.1" spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" diff --git a/gemfiles/active_record_42.gemfile b/gemfiles/active_record_42.gemfile index 30ece1b..e80d71c 100644 --- a/gemfiles/active_record_42.gemfile +++ b/gemfiles/active_record_42.gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' -gem 'activerecord', '~> 4.2.0.beta1', :require => 'active_record' -gem 'activesupport', '~> 4.2.0.beta1', :require => 'active_support' +gem 'activerecord', '~> 4.2.4', :require => 'active_record' +gem 'activesupport', '~> 4.2.4', :require => 'active_support' platforms :ruby do if RUBY_VERSION > "2.1.0" diff --git a/gemfiles/active_record_edge.gemfile b/gemfiles/active_record_50.gemfile similarity index 65% rename from gemfiles/active_record_edge.gemfile rename to gemfiles/active_record_50.gemfile index 360778a..919ba6b 100644 --- a/gemfiles/active_record_edge.gemfile +++ b/gemfiles/active_record_50.gemfile @@ -1,11 +1,7 @@ source 'https://rubygems.org' -git 'git://github.com/rails/rails.git' do - gem 'activerecord', :require => 'active_record' - gem 'activesupport', :require => 'active_support' -end - -gem 'arel', :github => 'rails/arel' +gem 'activerecord', '>= 5.0.0.beta1', '< 5.1', require: 'active_record' +gem 'activesupport', '>= 5.0.0.beta1', '< 5.1', require: 'active_support' platforms :ruby do if RUBY_VERSION > "2.1.0" diff --git a/lib/acts_as_paranoid.rb b/lib/acts_as_paranoid.rb index 7541c45..a8ada86 100644 --- a/lib/acts_as_paranoid.rb +++ b/lib/acts_as_paranoid.rb @@ -2,6 +2,7 @@ require 'acts_as_paranoid/associations' require 'acts_as_paranoid/validations' require 'acts_as_paranoid/relation' +require 'acts_as_paranoid/preloader_association' module ActsAsParanoid @@ -26,7 +27,8 @@ def acts_as_paranoid(options = {}) dependent_destroy_paranoid_only: false, without_default_scope: false } - self.paranoid_configuration[:deleted_value] = "deleted" if options[:column_type].to_s == "string" + self.paranoid_configuration.merge!(deleted_value: "deleted") if options[:column_type] == "string" + self.paranoid_configuration.merge!(allow_nulls: true ) if options[:column_type] == "boolean" self.paranoid_configuration.merge!(options) # user options unless ['time', 'boolean', 'string'].include? paranoid_configuration[:column_type].to_s @@ -40,15 +42,15 @@ def acts_as_paranoid(options = {}) include ActsAsParanoid::Core # Magic! - default_scope { where(paranoid_default_scope_sql) } unless paranoid_configuration[:without_default_scope] + default_scope { where(paranoid_default_scope) } unless paranoid_configuration[:without_default_scope] if paranoid_configuration[:column_type].to_s == 'time' scope :deleted_inside_time_window, lambda {|time, window| deleted_after_time((time - window)).deleted_before_time((time + window)) } - scope :deleted_after_time, lambda { |time| where("#{paranoid_column} > ?", time) } - scope :deleted_before_time, lambda { |time| where("#{paranoid_column} < ?", time) } + scope :deleted_after_time, lambda { |time| where("#{self.table_name}.#{paranoid_column} > ?", time) } + scope :deleted_before_time, lambda { |time| where("#{self.table_name}.#{paranoid_column} < ?", time) } end end end @@ -64,3 +66,6 @@ def acts_as_paranoid(options = {}) # Push the recover callback onto the activerecord callback list ActiveRecord::Callbacks::CALLBACKS.push(:before_recover, :after_recover) + +# Use with_deleted in preloader build_scope +ActiveRecord::Associations::Preloader::Association.send :include, ActsAsParanoid::PreloaderAssociation diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 7e6c72c..4997e29 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -36,9 +36,11 @@ def without_deleted def only_deleted if string_type_with_deleted_value? - without_paranoid_default_scope.where("#{paranoid_column_reference} IS ?", paranoid_configuration[:deleted_value]) + without_paranoid_default_scope.where(paranoid_column_reference => paranoid_configuration[:deleted_value]) + elsif boolean_type_not_nullable? + without_paranoid_default_scope.where(paranoid_column_reference => true) else - without_paranoid_default_scope.where("#{paranoid_column_reference} IS NOT ?", nil) + without_paranoid_default_scope.where.not(paranoid_column_reference => nil) end end @@ -50,13 +52,15 @@ def delete_all(conditions = nil) where(conditions).update_all(["#{paranoid_configuration[:column]} = ?", delete_now_value]) end - def paranoid_default_scope_sql + def paranoid_default_scope if string_type_with_deleted_value? self.all.table[paranoid_column].eq(nil). - or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value].to_s)). - to_sql + or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value])) + # or(self.all.table[paranoid_column].not_eq(paranoid_configuration[:deleted_value].to_s)).to_sql # opengov version + elsif boolean_type_not_nullable? + self.all.table[paranoid_column].eq(false) else - self.all.table[paranoid_column].eq(nil).to_sql + self.all.table[paranoid_column].eq(nil) end end @@ -64,6 +68,10 @@ def string_type_with_deleted_value? paranoid_column_type == :string && !paranoid_configuration[:deleted_value].nil? end + def boolean_type_not_nullable? + paranoid_column_type == :boolean && !paranoid_configuration[:allow_nulls] + end + def paranoid_column paranoid_configuration[:column].to_sym end @@ -91,9 +99,15 @@ def delete_now_value def without_paranoid_default_scope scope = self.all - if scope.where_values.include? paranoid_default_scope_sql - # ActiveRecord 4.1 - scope.where_values.delete(paranoid_default_scope_sql) + + if ActiveRecord::VERSION::MAJOR < 5 + # ActiveRecord 4.0.* + scope = scope.with_default_scope if ActiveRecord::VERSION::MINOR < 1 + scope.where_values.delete(paranoid_default_scope) + else + scope = scope.unscope(where: paranoid_default_scope) + # Fix problems with unscope group chain + scope = scope.unscoped if scope.to_sql.include? paranoid_default_scope.to_sql end scope @@ -101,11 +115,10 @@ def without_paranoid_default_scope def with_paranoid_default_scope scope = self.all - unless scope.where_values.include? paranoid_default_scope_sql - scope = scope.where(paranoid_default_scope_sql) - end - scope + return scope if scope.where_values.include? paranoid_default_scope_sql + + scope.where(paranoid_default_scope_sql) end end @@ -152,9 +165,7 @@ def destroy! end end - def destroy - destroy! - end + alias_method :destroy, :destroy! def recover(options={}) options = { @@ -207,8 +218,13 @@ def destroy_paranoid_associations end def deleted? - !(paranoid_value.nil? || - (self.class.string_type_with_deleted_value? && paranoid_value != self.class.delete_now_value)) + !if self.class.string_type_with_deleted_value? + paranoid_value != self.class.delete_now_value || paranoid_value.nil? + elsif self.class.boolean_type_not_nullable? + paranoid_value == false + else + paranoid_value.nil? + end end alias_method :destroyed?, :deleted? diff --git a/lib/acts_as_paranoid/preloader_association.rb b/lib/acts_as_paranoid/preloader_association.rb new file mode 100644 index 0000000..dda1a85 --- /dev/null +++ b/lib/acts_as_paranoid/preloader_association.rb @@ -0,0 +1,15 @@ +module ActsAsParanoid + module PreloaderAssociation + def self.included(base) + base.class_eval do + def build_scope_with_deleted + scope = build_scope_without_deleted + scope = scope.with_deleted if options[:with_deleted] && klass.respond_to?(:with_deleted) + scope + end + + alias_method_chain :build_scope, :deleted + end + end + end +end diff --git a/lib/acts_as_paranoid/validations.rb b/lib/acts_as_paranoid/validations.rb index d0dc80b..b70007b 100644 --- a/lib/acts_as_paranoid/validations.rb +++ b/lib/acts_as_paranoid/validations.rb @@ -6,42 +6,76 @@ def self.included(base) base.extend ClassMethods end - class UniquenessWithoutDeletedValidator < ActiveRecord::Validations::UniquenessValidator - def validate_each(record, attribute, value) - finder_class = find_finder_class_for(record) - table = finder_class.arel_table - - # TODO: Use record.class.column_types[attribute.to_s].coder ? - coder = record.class.column_types[attribute.to_s] - - if value && coder - value = if coder.respond_to? :type_cast_for_database - coder.type_cast_for_database value - else - coder.type_cast_for_write value - end + class UniquenessWithoutDeletedValidator + def self.[](version) + version = version.to_s + name = "V#{version.tr('.', '_')}" + unless constants.include? name.to_sym + raise "Unknown validator version #{version.inspect}; expected one of #{constants.sort.join(', ')}" end + const_get name + end + + class V5 < ActiveRecord::Validations::UniquenessValidator + def validate_each(record, attribute, value) + finder_class = find_finder_class_for(record) + table = finder_class.arel_table + + coder = record.class.attribute_types[attribute.to_s] + value = coder.type_cast_for_schema value if value && coder - relation = build_relation(finder_class, table, attribute, value) - [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value| - relation = relation.and(table[pk_key.to_sym].not_eq(pk_value)) - end if record.persisted? + relation = build_relation(finder_class, table, attribute, value) + [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value| + relation = relation.where(table[pk_key.to_sym].not_eq(pk_value)) + end if record.persisted? - Array.wrap(options[:scope]).each do |scope_item| - scope_value = record.send(scope_item) - relation = relation.and(table[scope_item].eq(scope_value)) + Array.wrap(options[:scope]).each do |scope_item| + relation = relation.where(table[scope_item].eq(record.public_send(scope_item))) + end + + if relation.where(finder_class.paranoid_default_scope).where(relation).exists? + record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value)) + end end + end + + class V4 < ActiveRecord::Validations::UniquenessValidator + def validate_each(record, attribute, value) + finder_class = find_finder_class_for(record) + table = finder_class.arel_table + + # TODO: Use record.class.column_types[attribute.to_s].coder ? + coder = record.class.column_types[attribute.to_s] + + if value && coder + value = if coder.respond_to? :type_cast_for_database + coder.type_cast_for_database value + else + coder.type_cast_for_write value + end + end + + relation = build_relation(finder_class, table, attribute, value) + [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value| + relation = relation.and(table[pk_key.to_sym].not_eq(pk_value)) + end if record.persisted? + + Array.wrap(options[:scope]).each do |scope_item| + scope_value = record.send(scope_item) + relation = relation.and(table[scope_item].eq(scope_value)) + end - # Re-add ActsAsParanoid default scope conditions manually. - if finder_class.unscoped.where(finder_class.paranoid_default_scope_sql).where(relation).exists? - record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value)) + # Re-add ActsAsParanoid default scope conditions manually. + if finder_class.unscoped.where(finder_class.paranoid_default_scope).where(relation).exists? + record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value)) + end end end end module ClassMethods def validates_uniqueness_of_without_deleted(*attr_names) - validates_with UniquenessWithoutDeletedValidator, _merge_attributes(attr_names) + validates_with UniquenessWithoutDeletedValidator[ActiveRecord::VERSION::MAJOR], _merge_attributes(attr_names) end end end diff --git a/lib/acts_as_paranoid/version.rb b/lib/acts_as_paranoid/version.rb index 00fc7c2..711a7f8 100644 --- a/lib/acts_as_paranoid/version.rb +++ b/lib/acts_as_paranoid/version.rb @@ -1,3 +1,3 @@ module ActsAsParanoid - VERSION = "0.5.0.beta1" + VERSION = "0.5.0.rc1" end diff --git a/test/test_core.rb b/test/test_core.rb index 5a602b2..507e33a 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -338,8 +338,8 @@ def test_recovery_callbacks @paranoid_with_callback.recover end - assert @paranoid_with_callback.called_before_recover - assert @paranoid_with_callback.called_after_recover + assert @paranoid_with_callback.called_before_recover + assert @paranoid_with_callback.called_after_recover end def test_delete_by_multiple_id_is_paranoid @@ -466,4 +466,44 @@ def test_string_type_with_no_nil_value_after_destroyed_twice_without_scope 2.times { ps.destroy } assert_equal 0, LessParanoidString.with_deleted.where(:id => ps).count end + + # Test boolean type columns, that are not nullable + def test_boolean_type_with_no_nil_value_before_destroy + ps = ParanoidBooleanNotNullable.create!() + assert_equal 1, ParanoidBooleanNotNullable.where(:id => ps).count + end + + def test_boolean_type_with_no_nil_value_after_destroy + ps = ParanoidBooleanNotNullable.create!() + ps.destroy + assert_equal 0, ParanoidBooleanNotNullable.where(:id => ps).count + end + + def test_boolean_type_with_no_nil_value_before_destroy_with_deleted + ps = ParanoidBooleanNotNullable.create!() + assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count + end + + def test_boolean_type_with_no_nil_value_after_destroy_with_deleted + ps = ParanoidBooleanNotNullable.create!() + ps.destroy + assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count + end + + def test_boolean_type_with_no_nil_value_before_destroy_only_deleted + ps = ParanoidBooleanNotNullable.create!() + assert_equal 0, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count + end + + def test_boolean_type_with_no_nil_value_after_destroy_only_deleted + ps = ParanoidBooleanNotNullable.create!() + ps.destroy + assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count + end + + def test_boolean_type_with_no_nil_value_after_destroyed_twice + ps = ParanoidBooleanNotNullable.create!() + 2.times { ps.destroy } + assert_equal 0, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 7415f63..4c09564 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -113,14 +113,14 @@ def setup_db create_table :super_paranoids do |t| t.string :type - t.references :has_many_inherited_super_paranoidz + t.references :has_many_inherited_super_paranoidz, index: { name: 'index__sp_id_on_has_many_isp' } t.datetime :deleted_at timestamps t end create_table :has_many_inherited_super_paranoidzs do |t| - t.references :super_paranoidz + t.references :super_paranoidz, index: { name: 'index_has_many_isp_on_sp_id' } t.datetime :deleted_at timestamps t @@ -183,6 +183,33 @@ def setup_db t.string :paranoid_thing_type t.datetime :deleted_at end + + create_table :paranoid_boolean_not_nullables do |t| + t.string :name + t.boolean :deleted, :boolean, :null => false, :default => false + end + + create_table :paranoid_belongs_to_polymorphics do |t| + t.string :name + t.string :parent_type + t.integer :parent_id + t.datetime :deleted_at + + t.timestamps + end + + create_table :not_paranoid_has_many_as_parents do |t| + t.string :name + + t.timestamps + end + + create_table :paranoid_has_many_as_parents do |t| + t.string :name + t.datetime :deleted_at + + t.timestamps + end end end @@ -192,9 +219,12 @@ def timestamps(table) end def teardown_db - ActiveRecord::Base.connection.tables.each do |table| - ActiveRecord::Base.connection.drop_table(table) + tables = if ActiveRecord::VERSION::MAJOR < 5 + ActiveRecord::Base.connection.tables + else + ActiveRecord::Base.connection.data_sources end + tables.each { |table| ActiveRecord::Base.connection.drop_table(table) } end class ParanoidTime < ActiveRecord::Base @@ -383,6 +413,20 @@ class ParanoidWithScopedValidation < ActiveRecord::Base validates_uniqueness_of :name, :scope => :category end +class ParanoidBelongsToPolymorphic < ActiveRecord::Base + acts_as_paranoid + belongs_to :parent, :polymorphic => true, :with_deleted => true +end + +class NotParanoidHasManyAsParent < ActiveRecord::Base + has_many :paranoid_belongs_to_polymorphics, :as => :parent, :dependent => :destroy +end + +class ParanoidHasManyAsParent < ActiveRecord::Base + acts_as_paranoid + has_many :paranoid_belongs_to_polymorphics, :as => :parent, :dependent => :destroy +end + class ParanoidBaseTest < ActiveSupport::TestCase def setup setup_db @@ -460,3 +504,8 @@ class ParanoidSection < ActiveRecord::Base belongs_to :paranoid_time belongs_to :paranoid_thing, :polymorphic => true, :dependent => :destroy end + +class ParanoidBooleanNotNullable < ActiveRecord::Base + acts_as_paranoid column: 'deleted', column_type: 'boolean', allow_nulls: false +end + diff --git a/test/test_preloader_association.rb b/test/test_preloader_association.rb new file mode 100644 index 0000000..996e902 --- /dev/null +++ b/test/test_preloader_association.rb @@ -0,0 +1,27 @@ +require 'test_helper' + +class PreloaderAssociationTest < ParanoidBaseTest + def test_includes_with_deleted + paranoid_time = ParanoidTime.first + paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants.create(:name => 'dependant!') + + paranoid_time.destroy + + ParanoidHasManyDependant.with_deleted.includes(:paranoid_time_with_deleted).each do |hasmany| + assert_not_nil hasmany.paranoid_time_with_deleted + end + end + + def test_includes_with_deleted_with_polymorphic_parent + not_paranoid_parent = NotParanoidHasManyAsParent.create(name: 'not paranoid parent') + paranoid_parent = ParanoidHasManyAsParent.create(name: 'paranoid parent') + ParanoidBelongsToPolymorphic.create(:name => 'belongs_to', :parent => not_paranoid_parent) + ParanoidBelongsToPolymorphic.create(:name => 'belongs_to', :parent => paranoid_parent) + + paranoid_parent.destroy + + ParanoidBelongsToPolymorphic.with_deleted.includes(:parent).each do |hasmany| + assert_not_nil hasmany.parent + end + end +end From 6e81910319d0c0e45f562f72347a58a404fe3040 Mon Sep 17 00:00:00 2001 From: Robert Hromej Date: Wed, 4 Aug 2021 12:24:21 +0300 Subject: [PATCH 102/105] Upgrade to v0.5.0 and cherry pick bugfix commits for [PLTF-5041] (#8) * Update readme.md foreign_key => :parent_id TO :foreign_key => :parent_id * When recovering associated records, need to specify the table name when querying the recovery window. Otherwise, an 'ambiguous column' error is thrown * Thanks @mvz <3 * Execute tests on Ruby 2.2 as well * Update rails 4.2 to latest release for CI * Remove edge tests since Rails 5 is unsupported at this time * Bump version * ActiveRecord queries with includes now respect :with_deleted => true * Update core.rb Is better to use alias method instead of defining delegator methods. * Remove legacy observer reference * Add test for decrement counters * Manually decrement counters with activerecord >= 4.2 * Compatibility with Rails 5 * Running tests for Rails 5 with compatible versions of ruby * Fix typo * fix Default scope * Get working bundler before running tests Also add Ruby 2.3 and Jruby 9k to matrix * Add patch-levels to rvm rubies for travis CI * Added support for allow_nulls option for boolean column. * :scissors: * Clarify supported versions of Rails * Thank you @sjke for working on Rails 5 support * Some doc cleanups :nail_care: * Revert "Merge pull request #40 from paveldruzyak/master" This reverts commit 8df82c4af50725282a7b66bdb36dc2ae3ddcbe55, reversing changes made to 64bfe2f5af46c0344cb4d6b71e7cd0cc9775855f. * Document destroy_fully! Closes #51 See also 3c12279 * :nail_care: * Bump to first release candidate * Bump to final * `active_record v5.1` support * Remove type_cast_for_schema call and pass relation to exists? Co-authored-by: Jenya Zueva Co-authored-by: Cosmin A Co-authored-by: Zachary Scott Co-authored-by: Zachary Scott Co-authored-by: Teemu Kupari Co-authored-by: Ehsan Yousefi Co-authored-by: Matt Co-authored-by: Pavel Druziak Co-authored-by: Andrey Ponomarenko Co-authored-by: fmnoise@gmail.com Co-authored-by: Nu-hin Co-authored-by: itsmechlark Co-authored-by: Shane Cavanaugh --- .travis.yml | 2 -- lib/acts_as_paranoid/validations.rb | 14 +++++++++----- lib/acts_as_paranoid/version.rb | 2 +- test/test_associations.rb | 12 ++++++------ test/test_inheritance.rb | 4 ++-- test/test_relations.rb | 22 +++++++++++----------- 6 files changed, 29 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3555e6..907b682 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,6 @@ matrix: allow_failures: - rvm: ruby-head - rvm: rbx - - gemfile: gemfiles/active_record_40.gemfile - - gemfile: gemfiles/active_record_edge.gemfile - rvm: jruby - rvm: jruby-9.1.0.0 fast_finish: true diff --git a/lib/acts_as_paranoid/validations.rb b/lib/acts_as_paranoid/validations.rb index b70007b..12bd090 100644 --- a/lib/acts_as_paranoid/validations.rb +++ b/lib/acts_as_paranoid/validations.rb @@ -21,10 +21,7 @@ def validate_each(record, attribute, value) finder_class = find_finder_class_for(record) table = finder_class.arel_table - coder = record.class.attribute_types[attribute.to_s] - value = coder.type_cast_for_schema value if value && coder - - relation = build_relation(finder_class, table, attribute, value) + relation = build_relation(finder_class, attribute, value) [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value| relation = relation.where(table[pk_key.to_sym].not_eq(pk_value)) end if record.persisted? @@ -33,10 +30,17 @@ def validate_each(record, attribute, value) relation = relation.where(table[scope_item].eq(record.public_send(scope_item))) end - if relation.where(finder_class.paranoid_default_scope).where(relation).exists? + if relation.where(finder_class.paranoid_default_scope).exists?(relation) record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value)) end end + + protected + + def build_relation(klass, attribute, value) + return super(klass, klass.arel_table, attribute, value) if ActiveRecord::VERSION::MINOR == 0 + super + end end class V4 < ActiveRecord::Validations::UniquenessValidator diff --git a/lib/acts_as_paranoid/version.rb b/lib/acts_as_paranoid/version.rb index 711a7f8..dd7c2d6 100644 --- a/lib/acts_as_paranoid/version.rb +++ b/lib/acts_as_paranoid/version.rb @@ -1,3 +1,3 @@ module ActsAsParanoid - VERSION = "0.5.0.rc1" + VERSION = "0.5.0" end diff --git a/test/test_associations.rb b/test/test_associations.rb index f02495c..ebc7eff 100644 --- a/test/test_associations.rb +++ b/test/test_associations.rb @@ -52,8 +52,8 @@ def test_belongs_to_with_deleted paranoid_time.destroy - assert_nil paranoid_has_many_dependant.paranoid_time(true) - assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted(true) + assert_nil paranoid_has_many_dependant.reload.paranoid_time + assert_equal paranoid_time, paranoid_has_many_dependant.reload.paranoid_time_with_deleted end def test_belongs_to_polymorphic_with_deleted @@ -65,8 +65,8 @@ def test_belongs_to_polymorphic_with_deleted paranoid_time.destroy - assert_nil paranoid_has_many_dependant.paranoid_time(true) - assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted(true) + assert_nil paranoid_has_many_dependant.reload.paranoid_time + assert_equal paranoid_time, paranoid_has_many_dependant.reload.paranoid_time_polymorphic_with_deleted end def test_belongs_to_nil_polymorphic_with_deleted @@ -78,8 +78,8 @@ def test_belongs_to_nil_polymorphic_with_deleted paranoid_time.destroy - assert_nil paranoid_has_many_dependant.paranoid_time(true) - assert_nil paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted(true) + assert_nil paranoid_has_many_dependant.reload.paranoid_time + assert_nil paranoid_has_many_dependant.reload.paranoid_time_polymorphic_with_deleted end def test_belongs_to_options diff --git a/test/test_inheritance.rb b/test/test_inheritance.rb index d4a3f57..91b58f7 100644 --- a/test/test_inheritance.rb +++ b/test/test_inheritance.rb @@ -5,10 +5,10 @@ def test_destroy_dependents_with_inheritance has_many_inherited_super_paranoidz = HasManyInheritedSuperParanoidz.new has_many_inherited_super_paranoidz.save has_many_inherited_super_paranoidz.super_paranoidz.create - assert_nothing_raised(NoMethodError) { has_many_inherited_super_paranoidz.destroy } + assert_nothing_raised { has_many_inherited_super_paranoidz.destroy } end def test_class_instance_variables_are_inherited - assert_nothing_raised(ActiveRecord::StatementInvalid) { InheritedParanoid.paranoid_column } + assert_nothing_raised { InheritedParanoid.paranoid_column } end end diff --git a/test/test_relations.rb b/test/test_relations.rb index bef6595..9141da7 100644 --- a/test/test_relations.rb +++ b/test/test_relations.rb @@ -82,8 +82,8 @@ def test_fake_removal_through_relation # destroy_all: through a relation @paranoid_forest_2.paranoid_trees.order(:id).destroy_all - assert_equal 0, @paranoid_forest_2.paranoid_trees(true).count - assert_equal 2, @paranoid_forest_2.paranoid_trees(true).with_deleted.count + assert_equal 0, @paranoid_forest_2.paranoid_trees.count + assert_equal 2, @paranoid_forest_2.paranoid_trees.with_deleted.count end def test_real_removal_through_relation @@ -97,21 +97,21 @@ def test_real_removal_through_relation paranoid_tree = @paranoid_forest_1.paranoid_trees.first @paranoid_forest_1.paranoid_trees.order(:id).destroy(paranoid_tree.id) @paranoid_forest_1.paranoid_trees.only_deleted.destroy(paranoid_tree.id) - assert_equal 1, @paranoid_forest_1.paranoid_trees(true).count - assert_equal 1, @paranoid_forest_1.paranoid_trees(true).with_deleted.count - assert_equal 0, @paranoid_forest_1.paranoid_trees(true).only_deleted.count + assert_equal 1, @paranoid_forest_1.paranoid_trees.count + assert_equal 1, @paranoid_forest_1.paranoid_trees.with_deleted.count + assert_equal 0, @paranoid_forest_1.paranoid_trees.only_deleted.count # destroy_all: two-step through a relation @paranoid_forest_1.paranoid_trees.order(:id).destroy_all @paranoid_forest_1.paranoid_trees.only_deleted.destroy_all - assert_equal 0, @paranoid_forest_1.paranoid_trees(true).count - assert_equal 0, @paranoid_forest_1.paranoid_trees(true).with_deleted.count - assert_equal 0, @paranoid_forest_1.paranoid_trees(true).only_deleted.count + assert_equal 0, @paranoid_forest_1.paranoid_trees.count + assert_equal 0, @paranoid_forest_1.paranoid_trees.with_deleted.count + assert_equal 0, @paranoid_forest_1.paranoid_trees.only_deleted.count # delete_all!: through a relation @paranoid_forest_2.paranoid_trees.order(:id).delete_all! - assert_equal 0, @paranoid_forest_2.paranoid_trees(true).count - assert_equal 0, @paranoid_forest_2.paranoid_trees(true).with_deleted.count - assert_equal 0, @paranoid_forest_2.paranoid_trees(true).only_deleted.count + assert_equal 0, @paranoid_forest_2.paranoid_trees.count + assert_equal 0, @paranoid_forest_2.paranoid_trees.with_deleted.count + assert_equal 0, @paranoid_forest_2.paranoid_trees.only_deleted.count end end From 777d5a07b4bbc14ea87f211620fc27577da5d654 Mon Sep 17 00:00:00 2001 From: Robert Hromej Date: Mon, 9 Aug 2021 17:24:27 +0300 Subject: [PATCH 103/105] Fix define_callbacks for rails5 (#9) --- lib/acts_as_paranoid/core.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/acts_as_paranoid/core.rb b/lib/acts_as_paranoid/core.rb index 4997e29..bc440a2 100644 --- a/lib/acts_as_paranoid/core.rb +++ b/lib/acts_as_paranoid/core.rb @@ -6,8 +6,8 @@ def self.included(base) module ClassMethods def self.extended(base) - base.define_callbacks :recover, terminator: lambda { |target, result| result == false } - base.define_callbacks :soft_destroy, terminator: lambda { |target, result| result == false } + base.define_callbacks :recover, terminator: lambda { |target, result| (result.is_a?(Proc) ? result.call : result) == false } + base.define_callbacks :soft_destroy, terminator: lambda { |target, result| (result.is_a?(Proc) ? result.call : result) == false } end def before_recover(method) From f0b3be53fa1da2e3d812e5c41f9adcb6c9f44cd5 Mon Sep 17 00:00:00 2001 From: Robert Hromej Date: Fri, 5 Nov 2021 12:11:58 +0200 Subject: [PATCH 104/105] Bump up the rails version to 5.1.X (#10) --- acts_as_paranoid.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acts_as_paranoid.gemspec b/acts_as_paranoid.gemspec index 0bdb3f9..f579c26 100644 --- a/acts_as_paranoid.gemspec +++ b/acts_as_paranoid.gemspec @@ -19,8 +19,8 @@ Gem::Specification.new do |spec| spec.required_rubygems_version = ">= 1.3.6" - spec.add_dependency "activerecord", ">= 4.0", "< 5.1" - spec.add_dependency "activesupport", ">= 4.0", "< 5.1" + spec.add_dependency "activerecord", ">= 4.0", "< 5.2" + spec.add_dependency "activesupport", ">= 4.0", "< 5.2" spec.add_development_dependency "bundler", "~> 1.5" spec.add_development_dependency "rake" From ac48a4352ef22cf4da3da16b0a180c802b05471e Mon Sep 17 00:00:00 2001 From: Robert Hromej Date: Mon, 29 Nov 2021 21:31:13 +0200 Subject: [PATCH 105/105] Fix deprecation warning using alias_method_chain (#11) --- lib/acts_as_paranoid/associations.rb | 6 ++++-- lib/acts_as_paranoid/preloader_association.rb | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/acts_as_paranoid/associations.rb b/lib/acts_as_paranoid/associations.rb index aa5a563..9f30d26 100644 --- a/lib/acts_as_paranoid/associations.rb +++ b/lib/acts_as_paranoid/associations.rb @@ -3,7 +3,8 @@ module Associations def self.included(base) base.extend ClassMethods class << base - alias_method_chain :belongs_to, :deleted + alias_method :belongs_to_without_deleted, :belongs_to + alias_method :belongs_to, :belongs_to_with_deleted end end @@ -27,7 +28,8 @@ def #{target}_with_unscoped(*args) return #{target}_without_unscoped(*args) unless association.klass.paranoid? association.klass.with_deleted.scoping { #{target}_without_unscoped(*args) } end - alias_method_chain :#{target}, :unscoped + alias_method :#{target}_without_unscoped, :#{target} + alias_method :#{target}, :#{target}_with_unscoped RUBY end end diff --git a/lib/acts_as_paranoid/preloader_association.rb b/lib/acts_as_paranoid/preloader_association.rb index dda1a85..5de838d 100644 --- a/lib/acts_as_paranoid/preloader_association.rb +++ b/lib/acts_as_paranoid/preloader_association.rb @@ -8,7 +8,8 @@ def build_scope_with_deleted scope end - alias_method_chain :build_scope, :deleted + alias_method :build_scope_without_deleted, :build_scope + alias_method :build_scope, :build_scope_with_deleted end end end