acts_as_paranoid 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsParanoid
2
4
  module Relation
3
5
  def self.included(base)
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/array/wrap'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/wrap"
2
4
 
3
5
  module ActsAsParanoid
4
6
  module Validations
@@ -6,80 +8,17 @@ module ActsAsParanoid
6
8
  base.extend ClassMethods
7
9
  end
8
10
 
9
- class UniquenessWithoutDeletedValidator
10
- def self.[](version)
11
- version = version.to_s
12
- name = "V#{version.tr('.', '_')}"
13
- unless constants.include? name.to_sym
14
- raise "Unknown validator version #{version.inspect}; expected one of #{constants.sort.join(', ')}"
15
- end
16
- const_get name
17
- end
18
-
19
- class V5 < ActiveRecord::Validations::UniquenessValidator
20
- def validate_each(record, attribute, value)
21
- finder_class = find_finder_class_for(record)
22
- table = finder_class.arel_table
23
-
24
- relation = build_relation(finder_class, attribute, value)
25
- [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
26
- relation = relation.where(table[pk_key.to_sym].not_eq(pk_value))
27
- end if record.persisted?
28
-
29
- Array.wrap(options[:scope]).each do |scope_item|
30
- relation = relation.where(table[scope_item].eq(record.public_send(scope_item)))
31
- end
32
-
33
- if relation.where(finder_class.paranoid_default_scope).exists?(relation)
34
- record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
35
- end
36
- end
37
-
38
- protected
39
-
40
- def build_relation(klass, attribute, value)
41
- return super(klass, klass.arel_table, attribute, value) if ActiveRecord::VERSION::MINOR == 0
42
- super
43
- end
44
- end
45
-
46
- class V4 < ActiveRecord::Validations::UniquenessValidator
47
- def validate_each(record, attribute, value)
48
- finder_class = find_finder_class_for(record)
49
- table = finder_class.arel_table
50
-
51
- # TODO: Use record.class.column_types[attribute.to_s].coder ?
52
- coder = record.class.column_types[attribute.to_s]
53
-
54
- if value && coder
55
- value = if coder.respond_to? :type_cast_for_database
56
- coder.type_cast_for_database value
57
- else
58
- coder.type_cast_for_write value
59
- end
60
- end
61
-
62
- relation = build_relation(finder_class, table, attribute, value)
63
- [Array(finder_class.primary_key), Array(record.send(:id))].transpose.each do |pk_key, pk_value|
64
- relation = relation.and(table[pk_key.to_sym].not_eq(pk_value))
65
- end if record.persisted?
66
-
67
- Array.wrap(options[:scope]).each do |scope_item|
68
- scope_value = record.send(scope_item)
69
- relation = relation.and(table[scope_item].eq(scope_value))
70
- end
11
+ class UniquenessWithoutDeletedValidator < ActiveRecord::Validations::UniquenessValidator
12
+ private
71
13
 
72
- # Re-add ActsAsParanoid default scope conditions manually.
73
- if finder_class.unscoped.where(finder_class.paranoid_default_scope).where(relation).exists?
74
- record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
75
- end
76
- end
14
+ def build_relation(klass, attribute, value)
15
+ super.where(klass.paranoid_default_scope)
77
16
  end
78
17
  end
79
18
 
80
19
  module ClassMethods
81
20
  def validates_uniqueness_of_without_deleted(*attr_names)
82
- validates_with UniquenessWithoutDeletedValidator[ActiveRecord::VERSION::MAJOR], _merge_attributes(attr_names)
21
+ validates_with UniquenessWithoutDeletedValidator, _merge_attributes(attr_names)
83
22
  end
84
23
  end
85
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActsAsParanoid
2
- VERSION = "0.6.0"
4
+ VERSION = "0.7.1"
3
5
  end
@@ -1,27 +1,34 @@
1
- require 'test_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
2
4
 
3
5
  class AssociationsTest < ParanoidBaseTest
4
- def test_removal_with_associations
5
- paranoid_company_1 = ParanoidDestroyCompany.create! :name => "ParanoidDestroyCompany #1"
6
- paranoid_company_2 = ParanoidDeleteCompany.create! :name => "ParanoidDestroyCompany #1"
7
- paranoid_company_1.paranoid_products.create! :name => "ParanoidProduct #1"
8
- paranoid_company_2.paranoid_products.create! :name => "ParanoidProduct #2"
6
+ def test_removal_with_destroy_associations
7
+ paranoid_company = ParanoidDestroyCompany.create! name: "ParanoidDestroyCompany #1"
8
+ paranoid_company.paranoid_products.create! name: "ParanoidProduct #1"
9
9
 
10
10
  assert_equal 1, ParanoidDestroyCompany.count
11
- assert_equal 1, ParanoidDeleteCompany.count
12
- assert_equal 2, ParanoidProduct.count
11
+ assert_equal 1, ParanoidProduct.count
13
12
 
14
13
  ParanoidDestroyCompany.first.destroy
15
14
  assert_equal 0, ParanoidDestroyCompany.count
16
- assert_equal 1, ParanoidProduct.count
15
+ assert_equal 0, ParanoidProduct.count
17
16
  assert_equal 1, ParanoidDestroyCompany.with_deleted.count
18
- assert_equal 2, ParanoidProduct.with_deleted.count
17
+ assert_equal 1, ParanoidProduct.with_deleted.count
19
18
 
20
19
  ParanoidDestroyCompany.with_deleted.first.destroy
21
20
  assert_equal 0, ParanoidDestroyCompany.count
22
- assert_equal 1, ParanoidProduct.count
21
+ assert_equal 0, ParanoidProduct.count
23
22
  assert_equal 0, ParanoidDestroyCompany.with_deleted.count
24
- assert_equal 1, ParanoidProduct.with_deleted.count
23
+ assert_equal 0, ParanoidProduct.with_deleted.count
24
+ end
25
+
26
+ def test_removal_with_delete_all_associations
27
+ paranoid_company = ParanoidDeleteCompany.create! name: "ParanoidDestroyCompany #1"
28
+ paranoid_company.paranoid_products.create! name: "ParanoidProduct #2"
29
+
30
+ assert_equal 1, ParanoidDeleteCompany.count
31
+ assert_equal 1, ParanoidProduct.count
25
32
 
26
33
  ParanoidDeleteCompany.first.destroy
27
34
  assert_equal 0, ParanoidDeleteCompany.count
@@ -38,40 +45,94 @@ class AssociationsTest < ParanoidBaseTest
38
45
 
39
46
  def test_belongs_to_with_scope_option
40
47
  paranoid_has_many_dependant = ParanoidHasManyDependant.new
48
+
49
+ expected_includes_values = ParanoidTime.includes(:not_paranoid).includes_values
50
+ includes_values = paranoid_has_many_dependant
51
+ .association(:paranoid_time_with_scope).scope.includes_values
52
+
53
+ assert_equal expected_includes_values, includes_values
54
+
55
+ paranoid_time = ParanoidTime.create(name: "not-hello")
56
+ paranoid_has_many_dependant.paranoid_time = paranoid_time
57
+ paranoid_has_many_dependant.save!
58
+
59
+ assert_nil paranoid_has_many_dependant.paranoid_time_with_scope
60
+
61
+ paranoid_time.update(name: "hello")
62
+
63
+ paranoid_has_many_dependant.reload
64
+
65
+ assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_scope
66
+
67
+ paranoid_time.destroy
68
+
69
+ paranoid_has_many_dependant.reload
70
+
71
+ assert_nil paranoid_has_many_dependant.paranoid_time_with_scope
72
+ end
73
+
74
+ def test_belongs_to_with_scope_and_deleted_option
75
+ paranoid_has_many_dependant = ParanoidHasManyDependant.new
41
76
  includes_values = ParanoidTime.includes(:not_paranoid).includes_values
42
77
 
43
- assert_equal includes_values, paranoid_has_many_dependant.association(:paranoid_time_with_scope).scope.includes_values
78
+ assert_equal includes_values, paranoid_has_many_dependant
79
+ .association(:paranoid_time_with_scope_with_deleted).scope.includes_values
80
+
81
+ paranoid_time = ParanoidTime.create(name: "not-hello")
82
+ paranoid_has_many_dependant.paranoid_time = paranoid_time
83
+ paranoid_has_many_dependant.save!
84
+
85
+ assert_nil paranoid_has_many_dependant.paranoid_time_with_scope_with_deleted
86
+
87
+ paranoid_time.update(name: "hello")
88
+ paranoid_has_many_dependant.reload
89
+
90
+ assert_equal paranoid_time, paranoid_has_many_dependant
91
+ .paranoid_time_with_scope_with_deleted
92
+
93
+ paranoid_time.destroy
94
+ paranoid_has_many_dependant.reload
95
+
96
+ assert_equal paranoid_time, paranoid_has_many_dependant
97
+ .paranoid_time_with_scope_with_deleted
44
98
  end
45
99
 
46
100
  def test_belongs_to_with_deleted
47
101
  paranoid_time = ParanoidTime.first
48
- paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants.create(:name => 'dependant!')
102
+ paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants
103
+ .create(name: "dependant!")
49
104
 
50
105
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time
51
106
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted
52
107
 
53
108
  paranoid_time.destroy
109
+ paranoid_has_many_dependant.reload
54
110
 
55
- assert_nil paranoid_has_many_dependant.reload.paranoid_time
56
- assert_equal paranoid_time, paranoid_has_many_dependant.reload.paranoid_time_with_deleted
111
+ assert_nil paranoid_has_many_dependant.paranoid_time
112
+ assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted
57
113
  end
58
114
 
59
115
  def test_belongs_to_polymorphic_with_deleted
60
116
  paranoid_time = ParanoidTime.first
61
- paranoid_has_many_dependant = ParanoidHasManyDependant.create!(:name => 'dependant!', :paranoid_time_polymorphic_with_deleted => paranoid_time)
117
+ paranoid_has_many_dependant = ParanoidHasManyDependant
118
+ .create!(name: "dependant!", paranoid_time_polymorphic_with_deleted: paranoid_time)
62
119
 
63
120
  assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time
64
- assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted
121
+ assert_equal paranoid_time, paranoid_has_many_dependant
122
+ .paranoid_time_polymorphic_with_deleted
65
123
 
66
124
  paranoid_time.destroy
67
125
 
68
126
  assert_nil paranoid_has_many_dependant.reload.paranoid_time
69
- assert_equal paranoid_time, paranoid_has_many_dependant.reload.paranoid_time_polymorphic_with_deleted
127
+ assert_equal paranoid_time, paranoid_has_many_dependant
128
+ .reload.paranoid_time_polymorphic_with_deleted
70
129
  end
71
130
 
72
131
  def test_belongs_to_nil_polymorphic_with_deleted
73
132
  paranoid_time = ParanoidTime.first
74
- paranoid_has_many_dependant = ParanoidHasManyDependant.create!(:name => 'dependant!', :paranoid_time_polymorphic_with_deleted => nil)
133
+ paranoid_has_many_dependant =
134
+ ParanoidHasManyDependant.create!(name: "dependant!",
135
+ paranoid_time_polymorphic_with_deleted: nil)
75
136
 
76
137
  assert_nil paranoid_has_many_dependant.paranoid_time
77
138
  assert_nil paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted
@@ -83,19 +144,23 @@ class AssociationsTest < ParanoidBaseTest
83
144
  end
84
145
 
85
146
  def test_belongs_to_options
86
- paranoid_time = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time]
147
+ paranoid_time = ParanoidHasManyDependant.reflections
148
+ .with_indifferent_access[:paranoid_time]
87
149
  assert_equal :belongs_to, paranoid_time.macro
88
150
  assert_nil paranoid_time.options[:with_deleted]
89
151
  end
90
152
 
91
153
  def test_belongs_to_with_deleted_options
92
- paranoid_time_with_deleted = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time_with_deleted]
154
+ paranoid_time_with_deleted =
155
+ ParanoidHasManyDependant.reflections
156
+ .with_indifferent_access[:paranoid_time_with_deleted]
93
157
  assert_equal :belongs_to, paranoid_time_with_deleted.macro
94
158
  assert paranoid_time_with_deleted.options[:with_deleted]
95
159
  end
96
160
 
97
161
  def test_belongs_to_polymorphic_with_deleted_options
98
- paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections.with_indifferent_access[:paranoid_time_polymorphic_with_deleted]
162
+ paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections
163
+ .with_indifferent_access[:paranoid_time_polymorphic_with_deleted]
99
164
  assert_equal :belongs_to, paranoid_time_polymorphic_with_deleted.macro
100
165
  assert paranoid_time_polymorphic_with_deleted.options[:with_deleted]
101
166
  end
@@ -118,6 +183,50 @@ class AssociationsTest < ParanoidBaseTest
118
183
  assert_equal [child], parent.paranoid_has_many_dependants.with_deleted.to_a
119
184
  end
120
185
 
186
+ def test_join_with_model_with_deleted
187
+ obj = ParanoidHasManyDependant.create(paranoid_time: ParanoidTime.create)
188
+ assert_not_nil obj.paranoid_time
189
+ assert_not_nil obj.paranoid_time_with_deleted
190
+
191
+ obj.paranoid_time.destroy
192
+ obj.reload
193
+
194
+ assert_nil obj.paranoid_time
195
+ assert_not_nil obj.paranoid_time_with_deleted
196
+
197
+ # Note that obj is destroyed because of dependent: :destroy in ParanoidTime
198
+ assert obj.destroyed?
199
+
200
+ assert_empty ParanoidHasManyDependant.with_deleted.joins(:paranoid_time)
201
+ assert_equal [obj],
202
+ ParanoidHasManyDependant.with_deleted.joins(:paranoid_time_with_deleted)
203
+ end
204
+
205
+ def test_includes_with_deleted
206
+ paranoid_time = ParanoidTime.first
207
+ paranoid_time.paranoid_has_many_dependants.create(name: "dependant!")
208
+
209
+ paranoid_time.destroy
210
+
211
+ ParanoidHasManyDependant.with_deleted
212
+ .includes(:paranoid_time_with_deleted).each do |hasmany|
213
+ assert_not_nil hasmany.paranoid_time_with_deleted
214
+ end
215
+ end
216
+
217
+ def test_includes_with_deleted_with_polymorphic_parent
218
+ not_paranoid_parent = NotParanoidHasManyAsParent.create(name: "not paranoid parent")
219
+ paranoid_parent = ParanoidHasManyAsParent.create(name: "paranoid parent")
220
+ ParanoidBelongsToPolymorphic.create(name: "belongs_to", parent: not_paranoid_parent)
221
+ ParanoidBelongsToPolymorphic.create(name: "belongs_to", parent: paranoid_parent)
222
+
223
+ paranoid_parent.destroy
224
+
225
+ ParanoidBelongsToPolymorphic.with_deleted.includes(:parent).each do |hasmany|
226
+ assert_not_nil hasmany.parent
227
+ end
228
+ end
229
+
121
230
  def test_cannot_find_a_paranoid_deleted_many_many_association
122
231
  left = ParanoidManyManyParentLeft.create
123
232
  right = ParanoidManyManyParentRight.create
@@ -128,8 +237,10 @@ class AssociationsTest < ParanoidBaseTest
128
237
  left.reload
129
238
 
130
239
  assert_equal [], left.paranoid_many_many_children, "Linking objects not deleted"
131
- assert_equal [], left.paranoid_many_many_parent_rights, "Associated objects not unlinked"
132
- assert_equal right, ParanoidManyManyParentRight.find(right.id), "Associated object deleted"
240
+ assert_equal [], left.paranoid_many_many_parent_rights,
241
+ "Associated objects not unlinked"
242
+ assert_equal right, ParanoidManyManyParentRight.find(right.id),
243
+ "Associated object deleted"
133
244
  end
134
245
 
135
246
  def test_cannot_find_a_paranoid_destroyed_many_many_association
@@ -142,11 +253,13 @@ class AssociationsTest < ParanoidBaseTest
142
253
  left.reload
143
254
 
144
255
  assert_equal [], left.paranoid_many_many_children, "Linking objects not deleted"
145
- assert_equal [], left.paranoid_many_many_parent_rights, "Associated objects not unlinked"
146
- assert_equal right, ParanoidManyManyParentRight.find(right.id), "Associated object deleted"
256
+ assert_equal [], left.paranoid_many_many_parent_rights,
257
+ "Associated objects not unlinked"
258
+ assert_equal right, ParanoidManyManyParentRight.find(right.id),
259
+ "Associated object deleted"
147
260
  end
148
261
 
149
- def test_cannot_find_a_has_many_through_object_when_its_linking_object_is_paranoid_destroyed
262
+ def test_cannot_find_a_has_many_through_object_when_its_linking_object_is_soft_destroyed
150
263
  left = ParanoidManyManyParentLeft.create
151
264
  right = ParanoidManyManyParentRight.create
152
265
  left.paranoid_many_many_parent_rights << right
@@ -175,8 +288,10 @@ class AssociationsTest < ParanoidBaseTest
175
288
  left.paranoid_many_many_parent_rights << right
176
289
 
177
290
  child = left.paranoid_many_many_children.first
178
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
179
- assert_equal right, child.paranoid_many_many_parent_right, "Child's right parent is incorrect"
291
+ assert_equal left, child.paranoid_many_many_parent_left,
292
+ "Child's left parent is incorrect"
293
+ assert_equal right, child.paranoid_many_many_parent_right,
294
+ "Child's right parent is incorrect"
180
295
 
181
296
  left.paranoid_many_many_parent_rights.clear
182
297
 
@@ -189,8 +304,10 @@ class AssociationsTest < ParanoidBaseTest
189
304
  left.paranoid_many_many_parent_rights << right
190
305
 
191
306
  child = left.paranoid_many_many_children.first
192
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
193
- assert_equal right, child.paranoid_many_many_parent_right, "Child's right parent is incorrect"
307
+ assert_equal left, child.paranoid_many_many_parent_left,
308
+ "Child's left parent is incorrect"
309
+ assert_equal right, child.paranoid_many_many_parent_right,
310
+ "Child's right parent is incorrect"
194
311
 
195
312
  left.paranoid_many_many_parent_rights.destroy(right)
196
313
 
@@ -203,8 +320,10 @@ class AssociationsTest < ParanoidBaseTest
203
320
  left.paranoid_many_many_parent_rights << right
204
321
 
205
322
  child = left.paranoid_many_many_children.first
206
- assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
207
- assert_equal right, child.paranoid_many_many_parent_right, "Child's right parent is incorrect"
323
+ assert_equal left, child.paranoid_many_many_parent_left,
324
+ "Child's left parent is incorrect"
325
+ assert_equal right, child.paranoid_many_many_parent_right,
326
+ "Child's right parent is incorrect"
208
327
 
209
328
  left.paranoid_many_many_parent_rights.delete(right)
210
329
 
@@ -228,12 +347,12 @@ class AssociationsTest < ParanoidBaseTest
228
347
  end
229
348
 
230
349
  def test_mass_assignment_of_paranoid_column_enabled
231
- if ActiveRecord::VERSION::MAJOR > 4 && ActiveRecord::VERSION::MINOR > 1
232
- skip 'Creation as deleted is not supported with Rails >= 5.2'
350
+ if Gem.loaded_specs["activerecord"].version >= Gem::Version.new("5.2.0")
351
+ skip "Creation as deleted is not supported with Rails >= 5.2"
233
352
  end
234
353
  now = Time.now
235
- record = ParanoidTime.create! :name => 'Foo', :deleted_at => now
236
- assert_equal 'Foo', record.name
354
+ record = ParanoidTime.create! name: "Foo", deleted_at: now
355
+ assert_equal "Foo", record.name
237
356
  assert_equal now, record.deleted_at
238
357
  end
239
358
  end
data/test/test_core.rb CHANGED
@@ -1,4 +1,6 @@
1
- require 'test_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
2
4
 
3
5
  class ParanoidTest < ParanoidBaseTest
4
6
  def test_paranoid?
@@ -69,6 +71,13 @@ class ParanoidTest < ParanoidBaseTest
69
71
  assert_not_nil pt.paranoid_value
70
72
  end
71
73
 
74
+ def test_non_persisted_delete
75
+ pt = ParanoidTime.new
76
+ assert_nil pt.paranoid_value
77
+ pt.delete
78
+ assert_not_nil pt.paranoid_value
79
+ end
80
+
72
81
  def test_non_persisted_destroy!
73
82
  pt = ParanoidTime.new
74
83
  assert_nil pt.paranoid_value
@@ -94,12 +103,34 @@ class ParanoidTest < ParanoidBaseTest
94
103
  assert_equal 1, ParanoidString.count
95
104
  end
96
105
 
106
+ def test_recovery!
107
+ ParanoidBoolean.first.destroy
108
+ ParanoidBoolean.create(name: "paranoid")
109
+
110
+ assert_raise do
111
+ ParanoidBoolean.only_deleted.first.recover!
112
+ end
113
+ end
114
+
115
+ # Rails does not allow saving deleted records
116
+ def test_no_save_after_destroy
117
+ paranoid = ParanoidString.first
118
+ paranoid.destroy
119
+ paranoid.name = "Let's update!"
120
+
121
+ assert_not paranoid.save
122
+ assert_raises ActiveRecord::RecordNotSaved do
123
+ paranoid.save!
124
+ end
125
+ end
126
+
97
127
  def setup_recursive_tests
98
128
  @paranoid_time_object = ParanoidTime.first
99
129
 
100
130
  # Create one extra ParanoidHasManyDependant record so that we can validate
101
131
  # the correct dependants are recovered.
102
- ParanoidTime.where('id <> ?', @paranoid_time_object.id).first.paranoid_has_many_dependants.create(:name => "should not be recovered").destroy
132
+ ParanoidTime.where("id <> ?", @paranoid_time_object.id).first
133
+ .paranoid_has_many_dependants.create(name: "should not be recovered").destroy
103
134
 
104
135
  @paranoid_boolean_count = ParanoidBoolean.count
105
136
 
@@ -108,20 +139,21 @@ class ParanoidTest < ParanoidBaseTest
108
139
  assert_equal 1, NotParanoid.count
109
140
 
110
141
  (1..3).each do |i|
111
- has_many_object = @paranoid_time_object.paranoid_has_many_dependants.create(:name => "has_many_#{i}")
112
- has_many_object.create_paranoid_belongs_dependant(:name => "belongs_to_#{i}")
142
+ has_many_object = @paranoid_time_object.paranoid_has_many_dependants
143
+ .create(name: "has_many_#{i}")
144
+ has_many_object.create_paranoid_belongs_dependant(name: "belongs_to_#{i}")
113
145
  has_many_object.save
114
146
 
115
- paranoid_boolean = @paranoid_time_object.paranoid_booleans.create(:name => "boolean_#{i}")
116
- paranoid_boolean.create_paranoid_has_one_dependant(:name => "has_one_#{i}")
147
+ paranoid_boolean = @paranoid_time_object.paranoid_booleans
148
+ .create(name: "boolean_#{i}")
149
+ paranoid_boolean.create_paranoid_has_one_dependant(name: "has_one_#{i}")
117
150
  paranoid_boolean.save
118
151
 
119
- @paranoid_time_object.not_paranoids.create(:name => "not_paranoid_a#{i}")
120
-
152
+ @paranoid_time_object.not_paranoids.create(name: "not_paranoid_a#{i}")
121
153
  end
122
154
 
123
- @paranoid_time_object.create_not_paranoid(:name => "not_paranoid_belongs_to")
124
- @paranoid_time_object.create_has_one_not_paranoid(:name => "has_one_not_paranoid")
155
+ @paranoid_time_object.create_not_paranoid(name: "not_paranoid_belongs_to")
156
+ @paranoid_time_object.create_has_one_not_paranoid(name: "has_one_not_paranoid")
125
157
 
126
158
  assert_equal 3, ParanoidTime.count
127
159
  assert_equal 3, ParanoidHasManyDependant.count
@@ -172,7 +204,7 @@ class ParanoidTest < ParanoidBaseTest
172
204
  @paranoid_time_object.destroy
173
205
  @paranoid_time_object.reload
174
206
 
175
- @paranoid_time_object.recover(:recursive => true)
207
+ @paranoid_time_object.recover(recursive: true)
176
208
 
177
209
  assert_equal 3, ParanoidTime.count
178
210
  assert_equal 3, ParanoidHasManyDependant.count
@@ -193,14 +225,14 @@ class ParanoidTest < ParanoidBaseTest
193
225
  @paranoid_time_object.paranoid_has_many_dependants.first.destroy
194
226
  end
195
227
  Time.stub :now, 1.hour.ago do
196
- @paranoid_time_object.paranoid_has_many_dependants.
197
- last.paranoid_belongs_dependant.
198
- destroy
228
+ @paranoid_time_object.paranoid_has_many_dependants
229
+ .last.paranoid_belongs_dependant
230
+ .destroy
199
231
  end
200
232
  @paranoid_time_object.destroy
201
233
  @paranoid_time_object.reload
202
234
 
203
- @paranoid_time_object.recover(:recursive => true)
235
+ @paranoid_time_object.recover(recursive: true)
204
236
 
205
237
  assert_equal 3, ParanoidTime.count
206
238
  assert_equal 2, ParanoidHasManyDependant.count
@@ -213,17 +245,17 @@ class ParanoidTest < ParanoidBaseTest
213
245
 
214
246
  def test_recursive_recovery_for_belongs_to_polymorphic
215
247
  child_1 = ParanoidAndroid.create
216
- section_1 = ParanoidSection.create(:paranoid_thing => child_1)
248
+ section_1 = ParanoidSection.create(paranoid_thing: child_1)
217
249
 
218
- child_2 = ParanoidPolygon.create(:sides => 3)
219
- section_2 = ParanoidSection.create(:paranoid_thing => child_2)
250
+ child_2 = ParanoidPolygon.create(sides: 3)
251
+ section_2 = ParanoidSection.create(paranoid_thing: child_2)
220
252
 
221
253
  assert_equal section_1.paranoid_thing, child_1
222
254
  assert_equal section_1.paranoid_thing.class, ParanoidAndroid
223
255
  assert_equal section_2.paranoid_thing, child_2
224
256
  assert_equal section_2.paranoid_thing.class, ParanoidPolygon
225
257
 
226
- parent = ParanoidTime.create(:name => "paranoid_parent")
258
+ parent = ParanoidTime.create(name: "paranoid_parent")
227
259
  parent.paranoid_sections << section_1
228
260
  parent.paranoid_sections << section_2
229
261
 
@@ -254,7 +286,7 @@ class ParanoidTest < ParanoidBaseTest
254
286
  @paranoid_time_object.destroy
255
287
  @paranoid_time_object.reload
256
288
 
257
- @paranoid_time_object.recover(:recursive => false)
289
+ @paranoid_time_object.recover(recursive: false)
258
290
 
259
291
  assert_equal 3, ParanoidTime.count
260
292
  assert_equal 0, ParanoidHasManyDependant.count
@@ -265,6 +297,24 @@ class ParanoidTest < ParanoidBaseTest
265
297
  assert_equal 0, HasOneNotParanoid.count
266
298
  end
267
299
 
300
+ def test_dirty
301
+ pt = ParanoidTime.create
302
+ pt.destroy
303
+ assert_not pt.changed?
304
+ end
305
+
306
+ def test_delete_dirty
307
+ pt = ParanoidTime.create
308
+ pt.delete
309
+ assert_not pt.changed?
310
+ end
311
+
312
+ def test_destroy_fully_dirty
313
+ pt = ParanoidTime.create
314
+ pt.destroy_fully!
315
+ assert_not pt.changed?
316
+ end
317
+
268
318
  def test_deleted?
269
319
  ParanoidTime.first.destroy
270
320
  assert ParanoidTime.with_deleted.first.deleted?
@@ -273,6 +323,43 @@ class ParanoidTest < ParanoidBaseTest
273
323
  assert ParanoidString.with_deleted.first.deleted?
274
324
  end
275
325
 
326
+ def test_delete_deleted?
327
+ ParanoidTime.first.delete
328
+ assert ParanoidTime.with_deleted.first.deleted?
329
+
330
+ ParanoidString.first.delete
331
+ assert ParanoidString.with_deleted.first.deleted?
332
+ end
333
+
334
+ def test_destroy_fully_deleted?
335
+ object = ParanoidTime.first
336
+ object.destroy_fully!
337
+ assert object.deleted?
338
+
339
+ object = ParanoidString.first
340
+ object.destroy_fully!
341
+ assert object.deleted?
342
+ end
343
+
344
+ def test_deleted_fully?
345
+ ParanoidTime.first.destroy
346
+ assert_not ParanoidTime.with_deleted.first.deleted_fully?
347
+
348
+ ParanoidString.first.destroy
349
+ assert ParanoidString.with_deleted.first.deleted?
350
+ end
351
+
352
+ def test_delete_deleted_fully?
353
+ ParanoidTime.first.delete
354
+ assert_not ParanoidTime.with_deleted.first.deleted_fully?
355
+ end
356
+
357
+ def test_destroy_fully_deleted_fully?
358
+ object = ParanoidTime.first
359
+ object.destroy_fully!
360
+ assert object.deleted_fully?
361
+ end
362
+
276
363
  def test_paranoid_destroy_callbacks
277
364
  @paranoid_with_callback = ParanoidWithCallback.first
278
365
  ParanoidWithCallback.transaction do
@@ -312,6 +399,14 @@ class ParanoidTest < ParanoidBaseTest
312
399
  assert @paranoid_with_callback.called_after_recover
313
400
  end
314
401
 
402
+ def test_recovery_callbacks_without_destroy
403
+ @paranoid_with_callback = ParanoidWithCallback.first
404
+ @paranoid_with_callback.recover
405
+
406
+ assert_nil @paranoid_with_callback.called_before_recover
407
+ assert_nil @paranoid_with_callback.called_after_recover
408
+ end
409
+
315
410
  def test_delete_by_multiple_id_is_paranoid
316
411
  model_a = ParanoidBelongsDependant.create
317
412
  model_b = ParanoidBelongsDependant.create
@@ -360,81 +455,207 @@ class ParanoidTest < ParanoidBaseTest
360
455
 
361
456
  # Test string type columns that don't have a nil value when not deleted (Y/N for example)
362
457
  def test_string_type_with_no_nil_value_before_destroy
363
- ps = ParanoidString.create!(:deleted => 'not dead')
364
- assert_equal 1, ParanoidString.where(:id => ps).count
458
+ ps = ParanoidString.create!(deleted: "not dead")
459
+ assert_equal 1, ParanoidString.where(id: ps).count
365
460
  end
366
461
 
367
462
  def test_string_type_with_no_nil_value_after_destroy
368
- ps = ParanoidString.create!(:deleted => 'not dead')
463
+ ps = ParanoidString.create!(deleted: "not dead")
369
464
  ps.destroy
370
- assert_equal 0, ParanoidString.where(:id => ps).count
465
+ assert_equal 0, ParanoidString.where(id: ps).count
371
466
  end
372
467
 
373
468
  def test_string_type_with_no_nil_value_before_destroy_with_deleted
374
- ps = ParanoidString.create!(:deleted => 'not dead')
375
- assert_equal 1, ParanoidString.with_deleted.where(:id => ps).count
469
+ ps = ParanoidString.create!(deleted: "not dead")
470
+ assert_equal 1, ParanoidString.with_deleted.where(id: ps).count
376
471
  end
377
472
 
378
473
  def test_string_type_with_no_nil_value_after_destroy_with_deleted
379
- ps = ParanoidString.create!(:deleted => 'not dead')
474
+ ps = ParanoidString.create!(deleted: "not dead")
380
475
  ps.destroy
381
- assert_equal 1, ParanoidString.with_deleted.where(:id => ps).count
476
+ assert_equal 1, ParanoidString.with_deleted.where(id: ps).count
382
477
  end
383
478
 
384
479
  def test_string_type_with_no_nil_value_before_destroy_only_deleted
385
- ps = ParanoidString.create!(:deleted => 'not dead')
386
- assert_equal 0, ParanoidString.only_deleted.where(:id => ps).count
480
+ ps = ParanoidString.create!(deleted: "not dead")
481
+ assert_equal 0, ParanoidString.only_deleted.where(id: ps).count
387
482
  end
388
483
 
389
484
  def test_string_type_with_no_nil_value_after_destroy_only_deleted
390
- ps = ParanoidString.create!(:deleted => 'not dead')
485
+ ps = ParanoidString.create!(deleted: "not dead")
391
486
  ps.destroy
392
- assert_equal 1, ParanoidString.only_deleted.where(:id => ps).count
487
+ assert_equal 1, ParanoidString.only_deleted.where(id: ps).count
393
488
  end
394
489
 
395
490
  def test_string_type_with_no_nil_value_after_destroyed_twice
396
- ps = ParanoidString.create!(:deleted => 'not dead')
491
+ ps = ParanoidString.create!(deleted: "not dead")
397
492
  2.times { ps.destroy }
398
- assert_equal 0, ParanoidString.with_deleted.where(:id => ps).count
493
+ assert_equal 0, ParanoidString.with_deleted.where(id: ps).count
399
494
  end
400
495
 
401
496
  # Test boolean type columns, that are not nullable
402
497
  def test_boolean_type_with_no_nil_value_before_destroy
403
- ps = ParanoidBooleanNotNullable.create!()
404
- assert_equal 1, ParanoidBooleanNotNullable.where(:id => ps).count
498
+ ps = ParanoidBooleanNotNullable.create!
499
+ assert_equal 1, ParanoidBooleanNotNullable.where(id: ps).count
405
500
  end
406
501
 
407
502
  def test_boolean_type_with_no_nil_value_after_destroy
408
- ps = ParanoidBooleanNotNullable.create!()
503
+ ps = ParanoidBooleanNotNullable.create!
409
504
  ps.destroy
410
- assert_equal 0, ParanoidBooleanNotNullable.where(:id => ps).count
505
+ assert_equal 0, ParanoidBooleanNotNullable.where(id: ps).count
411
506
  end
412
507
 
413
508
  def test_boolean_type_with_no_nil_value_before_destroy_with_deleted
414
- ps = ParanoidBooleanNotNullable.create!()
415
- assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
509
+ ps = ParanoidBooleanNotNullable.create!
510
+ assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
416
511
  end
417
512
 
418
513
  def test_boolean_type_with_no_nil_value_after_destroy_with_deleted
419
- ps = ParanoidBooleanNotNullable.create!()
514
+ ps = ParanoidBooleanNotNullable.create!
420
515
  ps.destroy
421
- assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
516
+ assert_equal 1, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
422
517
  end
423
518
 
424
519
  def test_boolean_type_with_no_nil_value_before_destroy_only_deleted
425
- ps = ParanoidBooleanNotNullable.create!()
426
- assert_equal 0, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count
520
+ ps = ParanoidBooleanNotNullable.create!
521
+ assert_equal 0, ParanoidBooleanNotNullable.only_deleted.where(id: ps).count
427
522
  end
428
523
 
429
524
  def test_boolean_type_with_no_nil_value_after_destroy_only_deleted
430
- ps = ParanoidBooleanNotNullable.create!()
525
+ ps = ParanoidBooleanNotNullable.create!
431
526
  ps.destroy
432
- assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(:id => ps).count
527
+ assert_equal 1, ParanoidBooleanNotNullable.only_deleted.where(id: ps).count
433
528
  end
434
529
 
435
530
  def test_boolean_type_with_no_nil_value_after_destroyed_twice
436
- ps = ParanoidBooleanNotNullable.create!()
531
+ ps = ParanoidBooleanNotNullable.create!
532
+ 2.times { ps.destroy }
533
+ assert_equal 0, ParanoidBooleanNotNullable.with_deleted.where(id: ps).count
534
+ end
535
+
536
+ def test_no_double_tap_destroys_fully
537
+ ps = ParanoidNoDoubleTapDestroysFully.create!
437
538
  2.times { ps.destroy }
438
- assert_equal 0, ParanoidBooleanNotNullable.with_deleted.where(:id => ps).count
539
+ assert_equal 1, ParanoidNoDoubleTapDestroysFully.with_deleted.where(id: ps).count
540
+ end
541
+
542
+ def test_decrement_counters_without_touch
543
+ paranoid_boolean = ParanoidBoolean.create!
544
+ paranoid_with_counter_cache = ParanoidWithCounterCache
545
+ .create!(paranoid_boolean: paranoid_boolean)
546
+
547
+ assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
548
+ updated_at = paranoid_boolean.reload.updated_at
549
+
550
+ paranoid_with_counter_cache.destroy
551
+
552
+ assert_equal 0, paranoid_boolean.reload.paranoid_with_counter_caches_count
553
+ assert_equal updated_at, paranoid_boolean.reload.updated_at
554
+ end
555
+
556
+ def test_decrement_custom_counters
557
+ paranoid_boolean = ParanoidBoolean.create!
558
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
559
+ .create!(paranoid_boolean: paranoid_boolean)
560
+
561
+ assert_equal 1, paranoid_boolean.custom_counter_cache
562
+
563
+ paranoid_with_custom_counter_cache.destroy
564
+
565
+ assert_equal 0, paranoid_boolean.reload.custom_counter_cache
566
+ end
567
+
568
+ def test_decrement_counters_with_touch
569
+ paranoid_boolean = ParanoidBoolean.create!
570
+ paranoid_with_counter_cache = ParanoidWithTouchAndCounterCache
571
+ .create!(paranoid_boolean: paranoid_boolean)
572
+
573
+ assert_equal 1, paranoid_boolean.paranoid_with_touch_and_counter_caches_count
574
+ updated_at = paranoid_boolean.reload.updated_at
575
+
576
+ paranoid_with_counter_cache.destroy
577
+
578
+ assert_equal 0, paranoid_boolean.reload.paranoid_with_touch_and_counter_caches_count
579
+ assert_not_equal updated_at, paranoid_boolean.reload.updated_at
580
+ end
581
+
582
+ def test_touch_belongs_to
583
+ paranoid_boolean = ParanoidBoolean.create!
584
+ paranoid_with_counter_cache = ParanoidWithTouch
585
+ .create!(paranoid_boolean: paranoid_boolean)
586
+
587
+ updated_at = paranoid_boolean.reload.updated_at
588
+
589
+ paranoid_with_counter_cache.destroy
590
+
591
+ assert_not_equal updated_at, paranoid_boolean.reload.updated_at
592
+ end
593
+
594
+ def test_destroy_with_optional_belongs_to_and_counter_cache
595
+ ps = ParanoidWithCounterCacheOnOptionalBelognsTo.create!
596
+ ps.destroy
597
+ assert_equal 1, ParanoidWithCounterCacheOnOptionalBelognsTo.only_deleted
598
+ .where(id: ps).count
599
+ end
600
+
601
+ def test_hard_destroy_decrement_counters
602
+ paranoid_boolean = ParanoidBoolean.create!
603
+ paranoid_with_counter_cache = ParanoidWithCounterCache
604
+ .create!(paranoid_boolean: paranoid_boolean)
605
+
606
+ assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
607
+
608
+ paranoid_with_counter_cache.destroy_fully!
609
+
610
+ assert_equal 0, paranoid_boolean.reload.paranoid_with_counter_caches_count
611
+ end
612
+
613
+ def test_hard_destroy_decrement_custom_counters
614
+ paranoid_boolean = ParanoidBoolean.create!
615
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
616
+ .create!(paranoid_boolean: paranoid_boolean)
617
+
618
+ assert_equal 1, paranoid_boolean.custom_counter_cache
619
+
620
+ paranoid_with_custom_counter_cache.destroy_fully!
621
+
622
+ assert_equal 0, paranoid_boolean.reload.custom_counter_cache
623
+ end
624
+
625
+ def test_increment_counters
626
+ paranoid_boolean = ParanoidBoolean.create!
627
+ paranoid_with_counter_cache = ParanoidWithCounterCache
628
+ .create!(paranoid_boolean: paranoid_boolean)
629
+
630
+ assert_equal 1, paranoid_boolean.paranoid_with_counter_caches_count
631
+
632
+ paranoid_with_counter_cache.destroy
633
+
634
+ assert_equal 0, paranoid_boolean.reload.paranoid_with_counter_caches_count
635
+
636
+ paranoid_with_counter_cache.recover
637
+
638
+ assert_equal 1, paranoid_boolean.reload.paranoid_with_counter_caches_count
639
+ end
640
+
641
+ def test_increment_custom_counters
642
+ paranoid_boolean = ParanoidBoolean.create!
643
+ paranoid_with_custom_counter_cache = ParanoidWithCustomCounterCache
644
+ .create!(paranoid_boolean: paranoid_boolean)
645
+
646
+ assert_equal 1, paranoid_boolean.custom_counter_cache
647
+
648
+ paranoid_with_custom_counter_cache.destroy
649
+
650
+ assert_equal 0, paranoid_boolean.reload.custom_counter_cache
651
+
652
+ paranoid_with_custom_counter_cache.recover
653
+
654
+ assert_equal 1, paranoid_boolean.reload.custom_counter_cache
655
+ end
656
+
657
+ def test_explicitly_setting_table_name_after_acts_as_paranoid_macro
658
+ assert_equal "explicit_table.deleted_at", ParanoidWithExplicitTableNameAfterMacro
659
+ .paranoid_column_reference
439
660
  end
440
661
  end