paranoia 2.0.5 → 2.1.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +1 -1
- data/lib/paranoia.rb +25 -44
- data/lib/paranoia/version.rb +1 -1
- data/test/paranoia_test.rb +81 -28
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b11cd914e35d9fcb7f01a85d9d9e5be2eddcc44
|
4
|
+
data.tar.gz: 095902bb8c728930c4058153cae56080074ca7c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 805b2fd483083762d26a1e4caa796c5af936f6a2e585e71753fc822326aa0978552746b236cd2f752d1f1591a37b8e171beb9dbd204010f985d979605a797b2c
|
7
|
+
data.tar.gz: d10fbd300d9ddf5e969c81f78a97312aac7160d46f7545351617fe6deb35c4e00b5b12ddb05a0ae1c4a2803683f5ecfbbd740a94bb4bc1c1ab3a6ead85e8db97
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
data/lib/paranoia.rb
CHANGED
@@ -57,27 +57,15 @@ module Paranoia
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def destroy
|
60
|
-
|
60
|
+
transaction do
|
61
61
|
run_callbacks(:destroy) do
|
62
62
|
touch_paranoia_column
|
63
63
|
end
|
64
64
|
end
|
65
|
-
callbacks_result ? self : false
|
66
|
-
end
|
67
|
-
|
68
|
-
# As of Rails 4.1.0 +destroy!+ will no longer remove the record from the db
|
69
|
-
# unless you touch the paranoia column before.
|
70
|
-
# We need to override it here otherwise children records might be removed
|
71
|
-
# when they shouldn't
|
72
|
-
if ActiveRecord::VERSION::STRING >= "4.1"
|
73
|
-
def destroy!
|
74
|
-
destroyed? ? super : destroy || raise(ActiveRecord::RecordNotDestroyed)
|
75
|
-
end
|
76
65
|
end
|
77
66
|
|
78
67
|
def delete
|
79
|
-
|
80
|
-
touch_paranoia_column(false)
|
68
|
+
touch_paranoia_column
|
81
69
|
end
|
82
70
|
|
83
71
|
def restore!(opts = {})
|
@@ -98,10 +86,10 @@ module Paranoia
|
|
98
86
|
end
|
99
87
|
alias :restore :restore!
|
100
88
|
|
101
|
-
def
|
89
|
+
def paranoia_destroyed?
|
102
90
|
send(paranoia_column) != paranoia_sentinel_value
|
103
91
|
end
|
104
|
-
alias :deleted? :
|
92
|
+
alias :deleted? :paranoia_destroyed?
|
105
93
|
|
106
94
|
private
|
107
95
|
|
@@ -109,16 +97,13 @@ module Paranoia
|
|
109
97
|
# insert time to paranoia column.
|
110
98
|
# @param with_transaction [Boolean] exec with ActiveRecord Transactions.
|
111
99
|
def touch_paranoia_column(with_transaction=false)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
with_transaction_returning_status { touch(paranoia_column) }
|
118
|
-
else
|
119
|
-
touch(paranoia_column)
|
120
|
-
end
|
100
|
+
raise ActiveRecord::ReadOnlyRecord, "#{self.class} is marked as readonly" if readonly?
|
101
|
+
if persisted?
|
102
|
+
touch(paranoia_column)
|
103
|
+
elsif !frozen?
|
104
|
+
write_attribute(paranoia_column, current_time_from_proper_timezone)
|
121
105
|
end
|
106
|
+
self
|
122
107
|
end
|
123
108
|
|
124
109
|
# restore associated records that have been soft deleted when
|
@@ -165,27 +150,30 @@ end
|
|
165
150
|
|
166
151
|
class ActiveRecord::Base
|
167
152
|
def self.acts_as_paranoid(options={})
|
168
|
-
alias :
|
169
|
-
alias :
|
153
|
+
alias :really_destroyed? :destroyed?
|
154
|
+
alias :really_delete :delete
|
155
|
+
|
156
|
+
alias :destroy_without_paranoia :destroy
|
170
157
|
def really_destroy!
|
171
158
|
dependent_reflections = self.class.reflections.select do |name, reflection|
|
172
159
|
reflection.options[:dependent] == :destroy
|
173
160
|
end
|
174
161
|
if dependent_reflections.any?
|
175
|
-
dependent_reflections.each do |name,
|
176
|
-
|
162
|
+
dependent_reflections.each do |name, reflection|
|
163
|
+
association_data = self.send(name)
|
177
164
|
# has_one association can return nil
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
165
|
+
# .paranoid? will work for both instances and classes
|
166
|
+
if association_data && association_data.paranoid?
|
167
|
+
if reflection.collection?
|
168
|
+
association_data.with_deleted.each(&:really_destroy!)
|
169
|
+
else
|
170
|
+
association_data.really_destroy!
|
171
|
+
end
|
184
172
|
end
|
185
173
|
end
|
186
174
|
end
|
187
|
-
|
188
|
-
|
175
|
+
write_attribute(paranoia_column, current_time_from_proper_timezone)
|
176
|
+
destroy_without_paranoia
|
189
177
|
end
|
190
178
|
|
191
179
|
include Paranoia
|
@@ -220,13 +208,6 @@ class ActiveRecord::Base
|
|
220
208
|
def self.paranoid? ; false ; end
|
221
209
|
def paranoid? ; self.class.paranoid? ; end
|
222
210
|
|
223
|
-
# Override the persisted method to allow for the paranoia gem.
|
224
|
-
# If a paranoid record is selected, then we only want to check
|
225
|
-
# if it's a new record, not if it is "destroyed".
|
226
|
-
def persisted?
|
227
|
-
paranoid? ? !new_record? : super
|
228
|
-
end
|
229
|
-
|
230
211
|
private
|
231
212
|
|
232
213
|
def paranoia_column
|
data/lib/paranoia/version.rb
CHANGED
data/test/paranoia_test.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
ActiveRecord::Base.raise_in_transactional_callbacks = true if ActiveRecord::VERSION::STRING >= '4.2'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
else
|
8
|
-
require 'test/unit'
|
9
|
-
Test::Unit::TestCase
|
10
|
-
end
|
4
|
+
require 'minitest/autorun'
|
5
|
+
test_framework = defined?(MiniTest::Test) ? MiniTest::Test : MiniTest::Unit::TestCase
|
6
|
+
|
11
7
|
require File.expand_path(File.dirname(__FILE__) + "/../lib/paranoia")
|
12
8
|
|
13
9
|
def connect!
|
@@ -136,6 +132,13 @@ class ParanoiaTest < test_framework
|
|
136
132
|
assert_equal 1, model.class.unscoped.count
|
137
133
|
end
|
138
134
|
|
135
|
+
def test_update_columns_on_paranoia_destroyed
|
136
|
+
record = ParentModel.create
|
137
|
+
record.destroy
|
138
|
+
|
139
|
+
assert record.update_columns deleted_at: Time.now
|
140
|
+
end
|
141
|
+
|
139
142
|
def test_scoping_behavior_for_paranoid_models
|
140
143
|
parent1 = ParentModel.create
|
141
144
|
parent2 = ParentModel.create
|
@@ -160,7 +163,7 @@ class ParanoiaTest < test_framework
|
|
160
163
|
model.destroy
|
161
164
|
|
162
165
|
assert_equal false, model.destroyed_at.nil?
|
163
|
-
assert model.
|
166
|
+
assert model.paranoia_destroyed?
|
164
167
|
|
165
168
|
assert_equal 0, model.class.count
|
166
169
|
assert_equal 1, model.class.unscoped.count
|
@@ -181,7 +184,7 @@ class ParanoiaTest < test_framework
|
|
181
184
|
model.destroy
|
182
185
|
|
183
186
|
assert DateTime.new(0) != model.deleted_at
|
184
|
-
assert model.
|
187
|
+
assert model.paranoia_destroyed?
|
185
188
|
|
186
189
|
assert_equal 0, model.class.count
|
187
190
|
assert_equal 1, model.class.unscoped.count
|
@@ -284,19 +287,61 @@ class ParanoiaTest < test_framework
|
|
284
287
|
assert model.instance_variable_get(:@destroy_callback_called)
|
285
288
|
end
|
286
289
|
|
290
|
+
def test_destroy_on_readonly_record
|
291
|
+
# Just to demonstrate the AR behaviour
|
292
|
+
model = NonParanoidModel.create!
|
293
|
+
model.readonly!
|
294
|
+
assert_raises ActiveRecord::ReadOnlyRecord do
|
295
|
+
model.destroy
|
296
|
+
end
|
297
|
+
|
298
|
+
# Mirrors behaviour above
|
299
|
+
model = ParanoidModel.create!
|
300
|
+
model.readonly!
|
301
|
+
assert_raises ActiveRecord::ReadOnlyRecord do
|
302
|
+
model.destroy
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_destroy_on_really_destroyed_record
|
307
|
+
model = ParanoidModel.create!
|
308
|
+
model.really_destroy!
|
309
|
+
assert model.really_destroyed?
|
310
|
+
assert model.paranoia_destroyed?
|
311
|
+
model.destroy
|
312
|
+
assert model.really_destroyed?
|
313
|
+
assert model.paranoia_destroyed?
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_destroy_on_unsaved_record
|
317
|
+
# Just to demonstrate the AR behaviour
|
318
|
+
model = NonParanoidModel.new
|
319
|
+
model.destroy!
|
320
|
+
assert model.really_destroyed?
|
321
|
+
model.destroy!
|
322
|
+
assert model.really_destroyed?
|
323
|
+
|
324
|
+
# Mirrors behaviour above
|
325
|
+
model = ParanoidModel.new
|
326
|
+
model.destroy!
|
327
|
+
assert model.paranoia_destroyed?
|
328
|
+
model.destroy!
|
329
|
+
assert model.paranoia_destroyed?
|
330
|
+
end
|
331
|
+
|
287
332
|
def test_restore
|
288
333
|
model = ParanoidModel.new
|
289
334
|
model.save
|
290
335
|
id = model.id
|
291
336
|
model.destroy
|
292
337
|
|
293
|
-
assert model.
|
338
|
+
assert model.paranoia_destroyed?
|
294
339
|
|
295
340
|
model = ParanoidModel.only_deleted.find(id)
|
296
341
|
model.restore!
|
297
342
|
model.reload
|
298
343
|
|
299
|
-
assert_equal false, model.
|
344
|
+
assert_equal false, model.paranoia_destroyed?
|
300
345
|
end
|
301
346
|
|
302
347
|
def test_restore_on_object_return_self
|
@@ -316,6 +361,16 @@ class ParanoiaTest < test_framework
|
|
316
361
|
assert_equal 1, ParanoidModel.unscoped.where(id: model.id).count
|
317
362
|
end
|
318
363
|
|
364
|
+
# Regression test for #92
|
365
|
+
def test_destroy_bang_twice
|
366
|
+
model = ParanoidModel.new
|
367
|
+
model.save!
|
368
|
+
model.destroy!
|
369
|
+
model.destroy!
|
370
|
+
|
371
|
+
assert_equal 1, ParanoidModel.unscoped.where(id: model.id).count
|
372
|
+
end
|
373
|
+
|
319
374
|
def test_destroy_return_value_on_success
|
320
375
|
model = ParanoidModel.create
|
321
376
|
return_value = model.destroy
|
@@ -336,7 +391,7 @@ class ParanoiaTest < test_framework
|
|
336
391
|
id = model.id
|
337
392
|
model.destroy
|
338
393
|
|
339
|
-
assert model.
|
394
|
+
assert model.paranoia_destroyed?
|
340
395
|
|
341
396
|
model = CallbackModel.only_deleted.find(id)
|
342
397
|
model.restore!
|
@@ -354,9 +409,15 @@ class ParanoiaTest < test_framework
|
|
354
409
|
|
355
410
|
def test_real_destroy_dependent_destroy
|
356
411
|
parent = ParentModel.create
|
357
|
-
|
412
|
+
child1 = parent.very_related_models.create
|
413
|
+
child2 = parent.non_paranoid_models.create
|
414
|
+
child3 = parent.create_non_paranoid_model
|
415
|
+
|
358
416
|
parent.really_destroy!
|
359
|
-
|
417
|
+
|
418
|
+
refute RelatedModel.unscoped.exists?(child1.id)
|
419
|
+
refute NonParanoidModel.unscoped.exists?(child2.id)
|
420
|
+
refute NonParanoidModel.unscoped.exists?(child3.id)
|
360
421
|
end
|
361
422
|
|
362
423
|
def test_real_destroy_dependent_destroy_after_normal_destroy
|
@@ -378,19 +439,10 @@ class ParanoiaTest < test_framework
|
|
378
439
|
assert RelatedModel.unscoped.exists?(child_2.id)
|
379
440
|
end
|
380
441
|
|
381
|
-
|
382
|
-
def test_real_destroy
|
383
|
-
model = ParanoidModel.new
|
384
|
-
model.save
|
385
|
-
model.destroy!
|
386
|
-
refute ParanoidModel.unscoped.exists?(model.id)
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
def test_real_delete
|
442
|
+
def test_really_delete
|
391
443
|
model = ParanoidModel.new
|
392
444
|
model.save
|
393
|
-
model.
|
445
|
+
model.really_delete
|
394
446
|
|
395
447
|
refute ParanoidModel.unscoped.exists?(model.id)
|
396
448
|
end
|
@@ -417,9 +469,9 @@ class ParanoiaTest < test_framework
|
|
417
469
|
b.reload
|
418
470
|
c.reload
|
419
471
|
|
420
|
-
refute a.
|
421
|
-
assert b.
|
422
|
-
refute c.
|
472
|
+
refute a.paranoia_destroyed?
|
473
|
+
assert b.paranoia_destroyed?
|
474
|
+
refute c.paranoia_destroyed?
|
423
475
|
end
|
424
476
|
|
425
477
|
def test_restore_with_associations
|
@@ -750,6 +802,7 @@ class ParentModel < ActiveRecord::Base
|
|
750
802
|
has_many :related_models
|
751
803
|
has_many :very_related_models, :class_name => 'RelatedModel', dependent: :destroy
|
752
804
|
has_many :non_paranoid_models, dependent: :destroy
|
805
|
+
has_one :non_paranoid_model, dependent: :destroy
|
753
806
|
has_many :asplode_models, dependent: :destroy
|
754
807
|
has_one :polymorphic_model, as: :parent, dependent: :destroy
|
755
808
|
end
|