jchupp-is_paranoid 0.5.0 → 0.6.0
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.
- data/VERSION.yml +1 -1
- data/lib/is_paranoid.rb +20 -5
- data/spec/is_paranoid_spec.rb +59 -22
- metadata +2 -2
data/VERSION.yml
CHANGED
data/lib/is_paranoid.rb
CHANGED
@@ -21,7 +21,8 @@ module IsParanoid
|
|
21
21
|
def self.included(base)
|
22
22
|
base.class_eval do
|
23
23
|
# This is the real magic. All calls made to this model will append
|
24
|
-
# the conditions deleted_at => nil
|
24
|
+
# the conditions deleted_at => nil (or whatever your destroyed_field
|
25
|
+
# and field_not_destroyed are). All exceptions require using
|
25
26
|
# exclusive_scope (see self.delete_all, self.count_with_destroyed,
|
26
27
|
# and self.find_with_destroyed )
|
27
28
|
default_scope :conditions => {destroyed_field => field_not_destroyed}
|
@@ -36,7 +37,10 @@ module IsParanoid
|
|
36
37
|
|
37
38
|
# Mark the model deleted_at as now.
|
38
39
|
def destroy_without_callbacks
|
39
|
-
self.
|
40
|
+
self.class.update_all(
|
41
|
+
"#{destroyed_field} = #{self.class.connection.quote(( field_destroyed.respond_to?(:call) ? field_destroyed.call : field_destroyed))}",
|
42
|
+
"id = #{self.id}"
|
43
|
+
)
|
40
44
|
end
|
41
45
|
|
42
46
|
# Override the default destroy to allow us to flag deleted_at.
|
@@ -51,10 +55,21 @@ module IsParanoid
|
|
51
55
|
result
|
52
56
|
end
|
53
57
|
|
54
|
-
#
|
55
|
-
#
|
58
|
+
# Use update_all with an exclusive scope to restore undo the soft-delete.
|
59
|
+
# This bypasses update-related callbacks
|
60
|
+
def self.restore(id)
|
61
|
+
with_exclusive_scope do
|
62
|
+
update_all(
|
63
|
+
"#{destroyed_field} = #{connection.quote(field_not_destroyed)}",
|
64
|
+
"id = #{id}"
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Set deleted_at flag on a model to field_not_destroyed, effectively
|
70
|
+
# undoing the soft-deletion.
|
56
71
|
def restore
|
57
|
-
self.
|
72
|
+
self.class.restore(id)
|
58
73
|
end
|
59
74
|
|
60
75
|
# find_with_destroyed and other blah_with_destroyed and
|
data/spec/is_paranoid_spec.rb
CHANGED
@@ -7,7 +7,13 @@ end
|
|
7
7
|
|
8
8
|
class Android < ActiveRecord::Base
|
9
9
|
validates_uniqueness_of :name
|
10
|
+
|
10
11
|
is_paranoid
|
12
|
+
|
13
|
+
before_update :raise_hell
|
14
|
+
def raise_hell
|
15
|
+
raise "hell"
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
19
|
class AndroidWithScopedUniqueness < ActiveRecord::Base
|
@@ -16,24 +22,6 @@ class AndroidWithScopedUniqueness < ActiveRecord::Base
|
|
16
22
|
is_paranoid
|
17
23
|
end
|
18
24
|
|
19
|
-
class NoCalculation < ActiveRecord::Base
|
20
|
-
is_paranoid
|
21
|
-
end
|
22
|
-
|
23
|
-
class Ninja < ActiveRecord::Base
|
24
|
-
validates_uniqueness_of :name, :scope => :visible
|
25
|
-
is_paranoid :field => [:visible, false, true]
|
26
|
-
end
|
27
|
-
|
28
|
-
class Pirate < ActiveRecord::Base
|
29
|
-
is_paranoid :field => [:alive, false, true]
|
30
|
-
end
|
31
|
-
|
32
|
-
class DeadPirate < ActiveRecord::Base
|
33
|
-
set_table_name :pirates
|
34
|
-
is_paranoid :field => [:alive, true, false]
|
35
|
-
end
|
36
|
-
|
37
25
|
describe Android do
|
38
26
|
before(:each) do
|
39
27
|
Android.delete_all
|
@@ -57,7 +45,7 @@ describe Android do
|
|
57
45
|
Android.count_with_destroyed.should == 2
|
58
46
|
end
|
59
47
|
|
60
|
-
it "should handle Model.destroy(id) properly" do
|
48
|
+
it "should handle Model.destroy(id) properly without hitting update/save related callbacks" do
|
61
49
|
lambda{
|
62
50
|
Android.destroy(@r2d2.id)
|
63
51
|
}.should change(Android, :count).from(2).to(1)
|
@@ -99,7 +87,7 @@ describe Android do
|
|
99
87
|
Android.count_with_destroyed.should == 2
|
100
88
|
end
|
101
89
|
|
102
|
-
it "should allow restoring" do
|
90
|
+
it "should allow restoring without hitting update/save related callbacks" do
|
103
91
|
@r2d2.destroy
|
104
92
|
lambda{
|
105
93
|
@r2d2.restore
|
@@ -129,13 +117,46 @@ describe Android do
|
|
129
117
|
another_r2d2.destroy
|
130
118
|
}.should_not raise_error
|
131
119
|
end
|
132
|
-
|
120
|
+
end
|
121
|
+
|
122
|
+
class Ninja < ActiveRecord::Base
|
123
|
+
validates_uniqueness_of :name, :scope => :visible
|
124
|
+
is_paranoid :field => [:visible, false, true]
|
125
|
+
end
|
126
|
+
|
127
|
+
class Pirate < ActiveRecord::Base
|
128
|
+
is_paranoid :field => [:alive, false, true]
|
129
|
+
end
|
130
|
+
|
131
|
+
class DeadPirate < ActiveRecord::Base
|
132
|
+
set_table_name :pirates
|
133
|
+
is_paranoid :field => [:alive, true, false]
|
134
|
+
end
|
135
|
+
|
136
|
+
class RandomPirate < ActiveRecord::Base
|
137
|
+
set_table_name :pirates
|
138
|
+
|
139
|
+
def after_destroy
|
140
|
+
raise 'after_destroy works'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
class UndestroyablePirate < ActiveRecord::Base
|
145
|
+
set_table_name :pirates
|
146
|
+
is_paranoid :field => [:alive, false, true]
|
147
|
+
|
148
|
+
def before_destroy
|
149
|
+
false
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe 'Ninjas and Pirates' do
|
133
154
|
it "should allow specifying alternate fields and field values" do
|
134
155
|
ninja = Ninja.create(:name => 'Esteban')
|
135
156
|
ninja.destroy
|
136
157
|
Ninja.first.should be_blank
|
137
158
|
Ninja.find_with_destroyed(:first).should == ninja
|
138
|
-
|
159
|
+
|
139
160
|
pirate = Pirate.create(:name => 'Reginald')
|
140
161
|
pirate.destroy
|
141
162
|
Pirate.first.should be_blank
|
@@ -146,4 +167,20 @@ describe Android do
|
|
146
167
|
DeadPirate.first.destroy
|
147
168
|
}.should change(Pirate, :count).from(0).to(1)
|
148
169
|
end
|
170
|
+
|
171
|
+
it "should handle before_destroy and after_destroy callbacks properly" do
|
172
|
+
edward = UndestroyablePirate.create(:name => 'Edward')
|
173
|
+
lambda{
|
174
|
+
edward.destroy
|
175
|
+
}.should_not change(UndestroyablePirate, :count)
|
176
|
+
|
177
|
+
raul = RandomPirate.create(:name => 'Raul')
|
178
|
+
lambda{
|
179
|
+
begin
|
180
|
+
edward.destroy
|
181
|
+
rescue => ex
|
182
|
+
ex.message.should == 'after_destroy works'
|
183
|
+
end
|
184
|
+
}.should_not change(RandomPirate, :count)
|
185
|
+
end
|
149
186
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jchupp-is_paranoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeffrey Chupp
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
12
|
+
date: 2009-04-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|