acts_as_paranoid 0.4.1 → 0.4.5
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.
- checksums.yaml +7 -0
- data/LICENSE +1 -1
- data/{README.markdown → README.md} +26 -17
- data/lib/acts_as_paranoid/core.rb +16 -8
- data/lib/acts_as_paranoid/relation.rb +2 -2
- data/lib/acts_as_paranoid/version.rb +3 -0
- data/lib/acts_as_paranoid.rb +10 -14
- data/test/test_associations.rb +222 -0
- data/test/test_core.rb +387 -0
- data/test/test_default_scopes.rb +52 -0
- data/test/test_helper.rb +442 -0
- data/test/test_inheritance.rb +14 -0
- data/test/test_observers.rb +16 -0
- data/test/test_relations.rb +117 -0
- data/test/test_validations.rb +42 -0
- metadata +102 -28
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 57c69c6d7676bda21b0f8da016bd556f77003894
|
4
|
+
data.tar.gz: 5293e8a3b417fecdfe117aefddcd8e2a0d2f4b09
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8ae49e59c2f487c80243bb42c4d6e33c4f1676ecd0d039ba420c1e1e49e02b83a4c6635515d1ef53dd4ba0c68ebce427b386ce684992d4139ef2e4c638f61dd5
|
7
|
+
data.tar.gz: f449a10feae541515688ed6c55446aa815025982f293a2375c44ec74b68a8cfe7928abc1dffee3758a868bca4d6d92eb13632642bb0dc40279d47e5973a7bfb0
|
data/LICENSE
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
# ActsAsParanoid
|
2
2
|
|
3
|
+
[](https://travis-ci.org/ActsAsParanoid/acts_as_paranoid)
|
4
|
+
|
3
5
|
A simple plugin which hides records instead of deleting them, being able to recover them.
|
4
6
|
|
5
7
|
**This branch targets Rails 3.2.** If you're working with another version, switch to the corresponding branch.
|
6
8
|
|
7
|
-
## Credits
|
8
|
-
|
9
|
-
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).
|
10
|
-
|
11
|
-
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.
|
12
|
-
|
13
9
|
## Usage
|
14
10
|
|
15
11
|
You can enable ActsAsParanoid like this:
|
@@ -186,29 +182,34 @@ Paranoiac.pretty.only_deleted.count #=> 1
|
|
186
182
|
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`
|
187
183
|
|
188
184
|
```ruby
|
189
|
-
class
|
190
|
-
|
185
|
+
class Parent < ActiveRecord::Base
|
186
|
+
has_many :children, :class_name => "ParanoiacChild"
|
191
187
|
end
|
192
188
|
|
193
189
|
class ParanoiacChild < ActiveRecord::Base
|
194
|
-
|
195
|
-
|
190
|
+
acts_as_paranoid
|
191
|
+
belongs_to :parent
|
192
|
+
|
193
|
+
# You may need to provide a foreign_key like this
|
194
|
+
belongs_to :parent_including_deleted, :class_name => "Parent", foreign_key => 'parent_id', :with_deleted => true
|
196
195
|
end
|
197
196
|
|
198
|
-
parent =
|
197
|
+
parent = Parent.first
|
199
198
|
child = parent.children.create
|
200
199
|
parent.destroy
|
201
200
|
|
202
201
|
child.parent #=> nil
|
203
|
-
child.
|
202
|
+
child.parent_including_deleted #=> Parent (it works!)
|
204
203
|
```
|
205
204
|
|
206
205
|
## Caveats
|
207
206
|
|
208
207
|
Watch out for these caveats:
|
209
208
|
|
209
|
+
|
210
210
|
- You cannot use scopes named `with_deleted` and `only_deleted`
|
211
211
|
- You cannot use scopes named `deleted_inside_time_window`, `deleted_before_time`, `deleted_after_time` **if** your paranoid column's type is `time`
|
212
|
+
- You cannot name association `*_with_deleted`
|
212
213
|
- `unscoped` will return all records, deleted or not
|
213
214
|
|
214
215
|
# Support
|
@@ -219,20 +220,21 @@ This gem supports the most recent versions of Rails and Ruby.
|
|
219
220
|
|
220
221
|
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:
|
221
222
|
|
222
|
-
|
223
|
+
gem "acts_as_paranoid", "~> 0.4.0"
|
223
224
|
|
224
225
|
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:
|
225
226
|
|
226
|
-
|
227
|
+
gem "rails3_acts_as_paranoid", "~>0.1.4"
|
227
228
|
|
228
229
|
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:
|
229
230
|
|
230
|
-
|
231
|
+
gem "rails3_acts_as_paranoid", "~>0.0.9"
|
231
232
|
|
232
233
|
|
233
234
|
## Ruby
|
234
235
|
|
235
|
-
This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode).
|
236
|
+
This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode).
|
237
|
+
|
236
238
|
|
237
239
|
# Acknowledgements
|
238
240
|
|
@@ -244,4 +246,11 @@ This gem is tested on Ruby 1.9, JRuby and Rubinius (both in 1.9 mode). It *might
|
|
244
246
|
* To [Craig Walker](https://github.com/softcraft-development) for Rails 3.1 support and fixing various pending issues
|
245
247
|
* To [Charles G.](https://github.com/chuckg) for Rails 3.2 support and for making a desperately needed global code refactoring
|
246
248
|
|
247
|
-
|
249
|
+
## Credits
|
250
|
+
|
251
|
+
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).
|
252
|
+
|
253
|
+
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.
|
254
|
+
|
255
|
+
|
256
|
+
Copyright © 2014 Zachary Scott, Gonçalo Silva, Rick Olson, released under the MIT license
|
@@ -94,7 +94,7 @@ module ActsAsParanoid
|
|
94
94
|
run_callbacks :destroy do
|
95
95
|
destroy_dependent_associations!
|
96
96
|
# Handle composite keys, otherwise we would just use `self.class.primary_key.to_sym => self.id`.
|
97
|
-
self.class.delete_all!(Hash[[Array(self.class.primary_key), Array(self.id)].transpose])
|
97
|
+
self.class.delete_all!(Hash[[Array(self.class.primary_key), Array(self.id)].transpose]) if persisted?
|
98
98
|
self.paranoid_value = self.class.delete_now_value
|
99
99
|
freeze
|
100
100
|
end
|
@@ -106,7 +106,7 @@ module ActsAsParanoid
|
|
106
106
|
with_transaction_returning_status do
|
107
107
|
run_callbacks :destroy do
|
108
108
|
# Handle composite keys, otherwise we would just use `self.class.primary_key.to_sym => self.id`.
|
109
|
-
self.class.delete_all(Hash[[Array(self.class.primary_key), Array(self.id)].transpose])
|
109
|
+
self.class.delete_all(Hash[[Array(self.class.primary_key), Array(self.id)].transpose]) if persisted?
|
110
110
|
self.paranoid_value = self.class.delete_now_value
|
111
111
|
self
|
112
112
|
end
|
@@ -134,17 +134,17 @@ module ActsAsParanoid
|
|
134
134
|
|
135
135
|
def recover_dependent_associations(window, options)
|
136
136
|
self.class.dependent_associations.each do |reflection|
|
137
|
-
next unless reflection.
|
137
|
+
next unless (klass = get_reflection_class(reflection)).paranoid?
|
138
138
|
|
139
|
-
scope =
|
139
|
+
scope = klass.only_deleted
|
140
140
|
|
141
141
|
# Merge in the association's scope
|
142
142
|
scope = scope.merge(association(reflection.name).association_scope)
|
143
143
|
|
144
144
|
# We can only recover by window if both parent and dependant have a
|
145
145
|
# paranoid column type of :time.
|
146
|
-
if self.class.paranoid_column_type == :time &&
|
147
|
-
scope = scope.merge(
|
146
|
+
if self.class.paranoid_column_type == :time && klass.paranoid_column_type == :time
|
147
|
+
scope = scope.merge(klass.deleted_inside_time_window(paranoid_value, window))
|
148
148
|
end
|
149
149
|
|
150
150
|
scope.each do |object|
|
@@ -155,9 +155,9 @@ module ActsAsParanoid
|
|
155
155
|
|
156
156
|
def destroy_dependent_associations!
|
157
157
|
self.class.dependent_associations.each do |reflection|
|
158
|
-
next unless reflection.
|
158
|
+
next unless (klass = get_reflection_class(reflection)).paranoid?
|
159
159
|
|
160
|
-
scope =
|
160
|
+
scope = klass.only_deleted
|
161
161
|
|
162
162
|
# Merge in the association's scope
|
163
163
|
scope = scope.merge(association(reflection.name).association_scope)
|
@@ -177,6 +177,14 @@ module ActsAsParanoid
|
|
177
177
|
|
178
178
|
private
|
179
179
|
|
180
|
+
def get_reflection_class(reflection)
|
181
|
+
if reflection.macro == :belongs_to && reflection.options.include?(:polymorphic)
|
182
|
+
self.send(reflection.foreign_type).constantize
|
183
|
+
else
|
184
|
+
reflection.klass
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
180
188
|
def paranoid_value=(value)
|
181
189
|
self.send("#{self.class.paranoid_column}=", value)
|
182
190
|
end
|
@@ -5,7 +5,7 @@ module ActsAsParanoid
|
|
5
5
|
def paranoid?
|
6
6
|
klass.try(:paranoid?) ? true : false
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def paranoid_deletion_attributes
|
10
10
|
{ klass.paranoid_column => klass.delete_now_value }
|
11
11
|
end
|
@@ -18,7 +18,7 @@ module ActsAsParanoid
|
|
18
18
|
orig_delete_all
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def delete_all(conditions = nil)
|
23
23
|
if paranoid?
|
24
24
|
update_all(paranoid_deletion_attributes, conditions)
|
data/lib/acts_as_paranoid.rb
CHANGED
@@ -1,27 +1,23 @@
|
|
1
|
-
require 'active_record/base'
|
2
|
-
require 'active_record/relation'
|
3
|
-
require 'active_record/callbacks'
|
4
1
|
require 'acts_as_paranoid/core'
|
5
2
|
require 'acts_as_paranoid/associations'
|
6
3
|
require 'acts_as_paranoid/validations'
|
7
4
|
require 'acts_as_paranoid/relation'
|
8
5
|
|
9
|
-
|
10
6
|
module ActsAsParanoid
|
11
|
-
|
7
|
+
|
12
8
|
def paranoid?
|
13
9
|
self.included_modules.include?(ActsAsParanoid::Core)
|
14
10
|
end
|
15
|
-
|
11
|
+
|
16
12
|
def validates_as_paranoid
|
17
13
|
include ActsAsParanoid::Validations
|
18
14
|
end
|
19
|
-
|
15
|
+
|
20
16
|
def acts_as_paranoid(options = {})
|
21
17
|
raise ArgumentError, "Hash expected, got #{options.class.name}" if not options.is_a?(Hash) and not options.empty?
|
22
|
-
|
18
|
+
|
23
19
|
class_attribute :paranoid_configuration, :paranoid_column_reference
|
24
|
-
|
20
|
+
|
25
21
|
self.paranoid_configuration = { :column => "deleted_at", :column_type => "time", :recover_dependent_associations => true, :dependent_recovery_window => 2.minutes }
|
26
22
|
self.paranoid_configuration.merge!({ :deleted_value => "deleted" }) if options[:column_type] == "string"
|
27
23
|
self.paranoid_configuration.merge!(options) # user options
|
@@ -29,11 +25,11 @@ module ActsAsParanoid
|
|
29
25
|
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]
|
30
26
|
|
31
27
|
self.paranoid_column_reference = "#{self.table_name}.#{paranoid_configuration[:column]}"
|
32
|
-
|
28
|
+
|
33
29
|
return if paranoid?
|
34
|
-
|
30
|
+
|
35
31
|
include ActsAsParanoid::Core
|
36
|
-
|
32
|
+
|
37
33
|
# Magic!
|
38
34
|
default_scope { where(paranoid_default_scope_sql) }
|
39
35
|
|
@@ -42,8 +38,8 @@ module ActsAsParanoid
|
|
42
38
|
deleted_after_time((time - window)).deleted_before_time((time + window))
|
43
39
|
}
|
44
40
|
|
45
|
-
scope :deleted_after_time, lambda { |time| where("#{paranoid_column} > ?", time) }
|
46
|
-
scope :deleted_before_time, lambda { |time| where("#{paranoid_column} < ?", time) }
|
41
|
+
scope :deleted_after_time, lambda { |time| where("#{self.table_name}.#{paranoid_column} > ?", time) }
|
42
|
+
scope :deleted_before_time, lambda { |time| where("#{self.table_name}.#{paranoid_column} < ?", time) }
|
47
43
|
end
|
48
44
|
end
|
49
45
|
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AssociationsTest < ParanoidBaseTest
|
4
|
+
def test_removal_with_associations
|
5
|
+
# This test shows that the current implementation doesn't handle
|
6
|
+
# assciation deletion correctly (when hard deleting via parent-object)
|
7
|
+
paranoid_company_1 = ParanoidDestroyCompany.create! :name => "ParanoidDestroyCompany #1"
|
8
|
+
paranoid_company_2 = ParanoidDeleteCompany.create! :name => "ParanoidDestroyCompany #1"
|
9
|
+
paranoid_company_1.paranoid_products.create! :name => "ParanoidProduct #1"
|
10
|
+
paranoid_company_2.paranoid_products.create! :name => "ParanoidProduct #2"
|
11
|
+
|
12
|
+
assert_equal 1, ParanoidDestroyCompany.count
|
13
|
+
assert_equal 1, ParanoidDeleteCompany.count
|
14
|
+
assert_equal 2, ParanoidProduct.count
|
15
|
+
|
16
|
+
ParanoidDestroyCompany.first.destroy
|
17
|
+
assert_equal 0, ParanoidDestroyCompany.count
|
18
|
+
assert_equal 1, ParanoidProduct.count
|
19
|
+
assert_equal 1, ParanoidDestroyCompany.with_deleted.count
|
20
|
+
assert_equal 2, ParanoidProduct.with_deleted.count
|
21
|
+
|
22
|
+
ParanoidDestroyCompany.with_deleted.first.destroy!
|
23
|
+
assert_equal 0, ParanoidDestroyCompany.count
|
24
|
+
assert_equal 1, ParanoidProduct.count
|
25
|
+
assert_equal 0, ParanoidDestroyCompany.with_deleted.count
|
26
|
+
assert_equal 1, ParanoidProduct.with_deleted.count
|
27
|
+
|
28
|
+
ParanoidDeleteCompany.with_deleted.first.destroy!
|
29
|
+
assert_equal 0, ParanoidDeleteCompany.count
|
30
|
+
assert_equal 0, ParanoidProduct.count
|
31
|
+
assert_equal 0, ParanoidDeleteCompany.with_deleted.count
|
32
|
+
assert_equal 0, ParanoidProduct.with_deleted.count
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_belongs_to_with_deleted
|
36
|
+
paranoid_time = ParanoidTime.first
|
37
|
+
paranoid_has_many_dependant = paranoid_time.paranoid_has_many_dependants.create(:name => 'dependant!')
|
38
|
+
|
39
|
+
assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time
|
40
|
+
assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted
|
41
|
+
|
42
|
+
paranoid_time.destroy
|
43
|
+
|
44
|
+
assert_nil paranoid_has_many_dependant.paranoid_time(true)
|
45
|
+
assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_with_deleted(true)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_belongs_to_polymorphic_with_deleted
|
49
|
+
paranoid_time = ParanoidTime.first
|
50
|
+
paranoid_has_many_dependant = ParanoidHasManyDependant.create!(:name => 'dependant!', :paranoid_time_polymorphic_with_deleted => paranoid_time)
|
51
|
+
|
52
|
+
assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time
|
53
|
+
assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted
|
54
|
+
|
55
|
+
paranoid_time.destroy
|
56
|
+
|
57
|
+
assert_nil paranoid_has_many_dependant.paranoid_time(true)
|
58
|
+
assert_equal paranoid_time, paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted(true)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_belongs_to_nil_polymorphic_with_deleted
|
62
|
+
paranoid_time = ParanoidTime.first
|
63
|
+
paranoid_has_many_dependant = ParanoidHasManyDependant.create!(:name => 'dependant!', :paranoid_time_polymorphic_with_deleted => nil)
|
64
|
+
|
65
|
+
assert_nil paranoid_has_many_dependant.paranoid_time
|
66
|
+
assert_nil paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted
|
67
|
+
|
68
|
+
paranoid_time.destroy
|
69
|
+
|
70
|
+
assert_nil paranoid_has_many_dependant.paranoid_time(true)
|
71
|
+
assert_nil paranoid_has_many_dependant.paranoid_time_polymorphic_with_deleted(true)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_belongs_to_options
|
75
|
+
paranoid_time = ParanoidHasManyDependant.reflections[:paranoid_time]
|
76
|
+
assert_equal :belongs_to, paranoid_time.macro
|
77
|
+
assert_nil paranoid_time.options[:with_deleted]
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_belongs_to_with_deleted_options
|
81
|
+
paranoid_time_with_deleted = ParanoidHasManyDependant.reflections[:paranoid_time_with_deleted]
|
82
|
+
assert_equal :belongs_to, paranoid_time_with_deleted.macro
|
83
|
+
assert paranoid_time_with_deleted.options[:with_deleted]
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_belongs_to_polymorphic_with_deleted_options
|
87
|
+
paranoid_time_polymorphic_with_deleted = ParanoidHasManyDependant.reflections[:paranoid_time_polymorphic_with_deleted]
|
88
|
+
assert_equal :belongs_to, paranoid_time_polymorphic_with_deleted.macro
|
89
|
+
assert paranoid_time_polymorphic_with_deleted.options[:with_deleted]
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_only_find_associated_records_when_finding_with_paranoid_deleted
|
93
|
+
parent = ParanoidBelongsDependant.create
|
94
|
+
child = ParanoidHasManyDependant.create
|
95
|
+
parent.paranoid_has_many_dependants << child
|
96
|
+
|
97
|
+
unrelated_parent = ParanoidBelongsDependant.create
|
98
|
+
unrelated_child = ParanoidHasManyDependant.create
|
99
|
+
unrelated_parent.paranoid_has_many_dependants << unrelated_child
|
100
|
+
|
101
|
+
child.destroy
|
102
|
+
assert_paranoid_deletion(child)
|
103
|
+
|
104
|
+
assert_equal [child], parent.paranoid_has_many_dependants.with_deleted.to_a
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_cannot_find_a_paranoid_deleted_many_many_association
|
108
|
+
left = ParanoidManyManyParentLeft.create
|
109
|
+
right = ParanoidManyManyParentRight.create
|
110
|
+
left.paranoid_many_many_parent_rights << right
|
111
|
+
|
112
|
+
left.paranoid_many_many_parent_rights.delete(right)
|
113
|
+
|
114
|
+
left.reload
|
115
|
+
|
116
|
+
assert_equal [], left.paranoid_many_many_children, "Linking objects not deleted"
|
117
|
+
assert_equal [], left.paranoid_many_many_parent_rights, "Associated objects not unlinked"
|
118
|
+
assert_equal right, ParanoidManyManyParentRight.find(right.id), "Associated object deleted"
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_cannot_find_a_paranoid_destroyed_many_many_association
|
122
|
+
left = ParanoidManyManyParentLeft.create
|
123
|
+
right = ParanoidManyManyParentRight.create
|
124
|
+
left.paranoid_many_many_parent_rights << right
|
125
|
+
|
126
|
+
left.paranoid_many_many_parent_rights.destroy(right)
|
127
|
+
|
128
|
+
left.reload
|
129
|
+
|
130
|
+
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"
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_cannot_find_a_has_many_through_object_when_its_linking_object_is_paranoid_destroyed
|
136
|
+
left = ParanoidManyManyParentLeft.create
|
137
|
+
right = ParanoidManyManyParentRight.create
|
138
|
+
left.paranoid_many_many_parent_rights << right
|
139
|
+
|
140
|
+
child = left.paranoid_many_many_children.first
|
141
|
+
|
142
|
+
child.destroy
|
143
|
+
|
144
|
+
left.reload
|
145
|
+
|
146
|
+
assert_equal [], left.paranoid_many_many_parent_rights, "Associated objects not deleted"
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_cannot_find_a_paranoid_deleted_model
|
150
|
+
model = ParanoidBelongsDependant.create
|
151
|
+
model.destroy
|
152
|
+
|
153
|
+
assert_raises ActiveRecord::RecordNotFound do
|
154
|
+
ParanoidBelongsDependant.find(model.id)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_bidirectional_has_many_through_association_clear_is_paranoid
|
159
|
+
left = ParanoidManyManyParentLeft.create
|
160
|
+
right = ParanoidManyManyParentRight.create
|
161
|
+
left.paranoid_many_many_parent_rights << right
|
162
|
+
|
163
|
+
child = left.paranoid_many_many_children.first
|
164
|
+
assert_equal left, child.paranoid_many_many_parent_left, "Child's left parent is incorrect"
|
165
|
+
assert_equal right, child.paranoid_many_many_parent_right, "Child's right parent is incorrect"
|
166
|
+
|
167
|
+
left.paranoid_many_many_parent_rights.clear
|
168
|
+
|
169
|
+
assert_paranoid_deletion(child)
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_bidirectional_has_many_through_association_destroy_is_paranoid
|
173
|
+
left = ParanoidManyManyParentLeft.create
|
174
|
+
right = ParanoidManyManyParentRight.create
|
175
|
+
left.paranoid_many_many_parent_rights << right
|
176
|
+
|
177
|
+
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"
|
180
|
+
|
181
|
+
left.paranoid_many_many_parent_rights.destroy(right)
|
182
|
+
|
183
|
+
assert_paranoid_deletion(child)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_bidirectional_has_many_through_association_delete_is_paranoid
|
187
|
+
left = ParanoidManyManyParentLeft.create
|
188
|
+
right = ParanoidManyManyParentRight.create
|
189
|
+
left.paranoid_many_many_parent_rights << right
|
190
|
+
|
191
|
+
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"
|
194
|
+
|
195
|
+
left.paranoid_many_many_parent_rights.delete(right)
|
196
|
+
|
197
|
+
assert_paranoid_deletion(child)
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_belongs_to_on_normal_model_is_paranoid
|
201
|
+
not_paranoid = HasOneNotParanoid.create
|
202
|
+
not_paranoid.paranoid_time = ParanoidTime.create
|
203
|
+
|
204
|
+
assert not_paranoid.save
|
205
|
+
assert_not_nil not_paranoid.paranoid_time
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_double_belongs_to_with_deleted
|
209
|
+
not_paranoid = DoubleHasOneNotParanoid.create
|
210
|
+
not_paranoid.paranoid_time = ParanoidTime.create
|
211
|
+
|
212
|
+
assert not_paranoid.save
|
213
|
+
assert_not_nil not_paranoid.paranoid_time
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_mass_assignment_of_paranoid_column_enabled
|
217
|
+
now = Time.now
|
218
|
+
record = ParanoidTime.create! :name => 'Foo', :deleted_at => now
|
219
|
+
assert_equal 'Foo', record.name
|
220
|
+
assert_equal now, record.deleted_at
|
221
|
+
end
|
222
|
+
end
|