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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bd7736219b3968e111105e25de4553f328a744c
4
- data.tar.gz: 3df48b961122c079b3565a2b3cc1f48b7b940fea
3
+ metadata.gz: 6b11cd914e35d9fcb7f01a85d9d9e5be2eddcc44
4
+ data.tar.gz: 095902bb8c728930c4058153cae56080074ca7c8
5
5
  SHA512:
6
- metadata.gz: 1df4bb3d86bcf7dcb932a11139acc9d68b8edadea446f64acdf370e9cde9b455684bf261f839949a826fcba3a77490252c6b15d027ad1cc4dc7853ca6ad702a7
7
- data.tar.gz: 61751265887e6a270b906433b9b3b03688344d683492abb2cbf4d91fa03f10f2b3db9c02b9e506b66175366e0581702671d2c54311b960dcdcba93238d2e9856
6
+ metadata.gz: 805b2fd483083762d26a1e4caa796c5af936f6a2e585e71753fc822326aa0978552746b236cd2f752d1f1591a37b8e171beb9dbd204010f985d979605a797b2c
7
+ data.tar.gz: d10fbd300d9ddf5e969c81f78a97312aac7160d46f7545351617fe6deb35c4e00b5b12ddb05a0ae1c4a2803683f5ecfbbd740a94bb4bc1c1ab3a6ead85e8db97
@@ -3,6 +3,7 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1.0
6
+ - 2.2.0
6
7
  - jruby-19mode
7
8
 
8
9
  env:
data/README.md CHANGED
@@ -139,7 +139,7 @@ Client.only_deleted
139
139
  If you want to check if a record is soft-deleted:
140
140
 
141
141
  ``` ruby
142
- client.destroyed?
142
+ client.paranoia_destroyed?
143
143
  # or
144
144
  client.deleted?
145
145
  ```
@@ -57,27 +57,15 @@ module Paranoia
57
57
  end
58
58
 
59
59
  def destroy
60
- callbacks_result = transaction do
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
- return if new_record?
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 destroyed?
89
+ def paranoia_destroyed?
102
90
  send(paranoia_column) != paranoia_sentinel_value
103
91
  end
104
- alias :deleted? :destroyed?
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
- # This method is (potentially) called from really_destroy
113
- # The object the method is being called on may be frozen
114
- # Let's not touch it if it's frozen.
115
- unless self.frozen?
116
- if with_transaction
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 :destroy! :destroy
169
- alias :delete! :delete
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
- associated_records = self.send(name)
162
+ dependent_reflections.each do |name, reflection|
163
+ association_data = self.send(name)
177
164
  # has_one association can return nil
178
- if associated_records && associated_records.respond_to?(:with_deleted)
179
- # Paranoid models will have this method, non-paranoid models will not
180
- associated_records.with_deleted.each(&:really_destroy!)
181
- self.send(name).reload
182
- elsif associated_records && !associated_records.respond_to?(:each) # single record
183
- associated_records.really_destroy!
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
- touch_paranoia_column if ActiveRecord::VERSION::STRING >= "4.1"
188
- destroy!
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
@@ -1,3 +1,3 @@
1
1
  module Paranoia
2
- VERSION = "2.0.5"
2
+ VERSION = "2.1.0.pre"
3
3
  end
@@ -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
- test_framework = if ActiveRecord::VERSION::STRING >= "4.1"
5
- require 'minitest/autorun'
6
- MiniTest::Test
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.destroyed?
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.destroyed?
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.destroyed?
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.destroyed?
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.destroyed?
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
- child = parent.very_related_models.create
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
- refute RelatedModel.unscoped.exists?(child.id)
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
- if ActiveRecord::VERSION::STRING < "4.1"
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.delete!
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.destroyed?
421
- assert b.destroyed?
422
- refute c.destroyed?
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paranoia
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
4
+ version: 2.1.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - radarlistener@gmail.com