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 CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 5
3
+ :minor: 6
4
4
  :patch: 0
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. Exceptions require using
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.update_attribute(destroyed_field, ( field_destroyed.respond_to?(:call) ? field_destroyed.call : field_destroyed))
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
- # Set deleted_at flag on a model to nil, effectively undoing the
55
- # soft-deletion.
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.update_attribute(destroyed_field, field_not_destroyed)
72
+ self.class.restore(id)
58
73
  end
59
74
 
60
75
  # find_with_destroyed and other blah_with_destroyed and
@@ -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.5.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 00:00:00 -07:00
12
+ date: 2009-04-22 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15