immortal 2.0.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +114 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +1 -1
- data/LICENSE.txt +21 -0
- data/README.md +21 -44
- data/Rakefile +2 -2
- data/immortal.gemspec +28 -21
- data/lib/immortal.rb +45 -39
- data/lib/immortal/belongs_to.rb +4 -3
- data/lib/immortal/belongs_to_builder.rb +25 -30
- data/lib/immortal/singular_association.rb +91 -109
- data/lib/immortal/version.rb +3 -0
- metadata +69 -10
- data/LICENSE +0 -9
- data/spec/immortal_spec.rb +0 -383
- data/spec/spec_helper.rb +0 -145
data/LICENSE
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
(The MIT License)
|
2
|
-
|
3
|
-
Copyright (c) Teambox
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
-
|
7
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
-
|
9
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/spec/immortal_spec.rb
DELETED
@@ -1,383 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
|
3
|
-
describe Immortal do
|
4
|
-
before do
|
5
|
-
@m = ImmortalModel.create! title: 'testing immortal'
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should not be deleted from the database using #destroy" do
|
9
|
-
expect {
|
10
|
-
@m.destroy
|
11
|
-
}.to_not change(ImmortalModel, :count_with_deleted)
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should be frozen using #destroy" do
|
15
|
-
@m.destroy
|
16
|
-
@m.should be_frozen
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should not be dirty using #destroy" do
|
20
|
-
@m.destroy
|
21
|
-
@m.should_not be_changed
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should not be dirty using #destroy" do
|
25
|
-
expect {
|
26
|
-
@m.destroy
|
27
|
-
}.to change(@m, :updated_at)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should be deleted from the database using #destroy!" do
|
31
|
-
expect {
|
32
|
-
@m.destroy!
|
33
|
-
}.to change(ImmortalModel, :count_with_deleted)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should find non deleted records" do
|
37
|
-
ImmortalModel.first.should == @m
|
38
|
-
ImmortalModel.all.should include(@m)
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should not find deleted records" do
|
42
|
-
@m.destroy
|
43
|
-
ImmortalModel.first.should be_nil
|
44
|
-
ImmortalModel.all.should be_empty
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should find deleted records using the old method" do
|
48
|
-
ImmortalModel.find_with_deleted(@m.id).should == @m
|
49
|
-
@m.destroy
|
50
|
-
ImmortalModel.find_with_deleted(@m.id).should == @m
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should count undeleted records by default" do
|
54
|
-
@m2 = ImmortalModel.create! title: 'testing immortal again'
|
55
|
-
ImmortalModel.count_only_deleted.should == 0
|
56
|
-
|
57
|
-
@m.destroy
|
58
|
-
|
59
|
-
ImmortalModel.count_only_deleted.should == 1
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should find only deleted records" do
|
63
|
-
@m2 = ImmortalModel.create! title: 'testing immortal again'
|
64
|
-
expect {
|
65
|
-
ImmortalModel.find_only_deleted(@m.id)
|
66
|
-
}.to raise_error(ActiveRecord::RecordNotFound)
|
67
|
-
|
68
|
-
@m.destroy
|
69
|
-
|
70
|
-
ImmortalModel.find_only_deleted(@m.id).should == @m
|
71
|
-
expect {
|
72
|
-
ImmortalModel.find_only_deleted(@m2.id)
|
73
|
-
}.to raise_error(ActiveRecord::RecordNotFound)
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should be able to count undeleted records" do
|
77
|
-
@m2 = ImmortalModel.create! title: 'testing immortal again'
|
78
|
-
ImmortalModel.count.should == 2
|
79
|
-
|
80
|
-
@m.destroy
|
81
|
-
|
82
|
-
ImmortalModel.count.should == 1
|
83
|
-
end
|
84
|
-
|
85
|
-
it "should be able to count all the records including deleted" do
|
86
|
-
@m2 = ImmortalModel.create! title: 'testing immortal again'
|
87
|
-
@m.destroy
|
88
|
-
ImmortalModel.count_with_deleted.should == 2
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should not exist if deleted" do
|
92
|
-
ImmortalModel.exists?(@m.id).should be_true
|
93
|
-
@m.destroy
|
94
|
-
ImmortalModel.exists?(@m.id).should be_false
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should calculate without deleted" do
|
98
|
-
@m2 = ImmortalModel.create! value: 10
|
99
|
-
@m3 = ImmortalModel.create! value: 20
|
100
|
-
ImmortalModel.calculate(:sum, :value).should == 30
|
101
|
-
@m2.destroy
|
102
|
-
ImmortalModel.calculate(:sum, :value).should == 20
|
103
|
-
end
|
104
|
-
|
105
|
-
it "should execute the before_destroy callback when immortally destroyed" do
|
106
|
-
@m.destroy
|
107
|
-
@m.before_d.should be_true
|
108
|
-
end
|
109
|
-
|
110
|
-
it "should execute the after_destroy callback when immortally destroyed" do
|
111
|
-
@m.destroy
|
112
|
-
@m.after_d.should be_true
|
113
|
-
end
|
114
|
-
|
115
|
-
it "should execute the after_commit callback when immortally destroyed" do
|
116
|
-
@m.after_commit = false
|
117
|
-
@m.destroy
|
118
|
-
@m.after_commit.should be_true
|
119
|
-
end
|
120
|
-
|
121
|
-
it "should not return true when a before hook halts" do
|
122
|
-
@m.before_return = false
|
123
|
-
@m.after_commit = false
|
124
|
-
@m.destroy.should be_false
|
125
|
-
@m.after_commit.should_not be_true
|
126
|
-
end
|
127
|
-
|
128
|
-
it "should not execute the before_update callback when immortally destroyed" do
|
129
|
-
@m.destroy
|
130
|
-
@m.before_u.should be_nil
|
131
|
-
end
|
132
|
-
|
133
|
-
it "should not execute the after_update callback when immortally destroyed" do
|
134
|
-
@m.destroy
|
135
|
-
@m.after_u.should be_nil
|
136
|
-
end
|
137
|
-
|
138
|
-
it "should not execute the before_destroy callback when immortally destroyed without callbacks" do
|
139
|
-
@m.destroy_without_callbacks
|
140
|
-
@m.before_d.should be_nil
|
141
|
-
end
|
142
|
-
|
143
|
-
it "should not execute the after_destroy callback when immortally destroyed without callbacks" do
|
144
|
-
@m.destroy_without_callbacks
|
145
|
-
@m.after_d.should be_nil
|
146
|
-
end
|
147
|
-
|
148
|
-
it "should immortally delete all records with delete_all" do
|
149
|
-
expect {
|
150
|
-
ImmortalModel.delete_all
|
151
|
-
}.to change(ImmortalModel, :count).by(-1)
|
152
|
-
ImmortalModel.count_with_deleted.should == 1
|
153
|
-
end
|
154
|
-
|
155
|
-
it "should immortally delete all records with delete_all!" do
|
156
|
-
expect {
|
157
|
-
ImmortalModel.delete_all!
|
158
|
-
}.to change(ImmortalModel, :count_with_deleted).by(-1)
|
159
|
-
end
|
160
|
-
|
161
|
-
it "should know if it's deleted" do
|
162
|
-
@m.should_not be_deleted
|
163
|
-
@m.destroy
|
164
|
-
@m.should be_deleted
|
165
|
-
end
|
166
|
-
|
167
|
-
it "should be recoverable" do
|
168
|
-
@m.destroy
|
169
|
-
@m = ImmortalModel.find_with_deleted(@m.id)
|
170
|
-
expect {
|
171
|
-
@m.recover!
|
172
|
-
}.to change(@m, :updated_at)
|
173
|
-
@m.should_not be_frozen
|
174
|
-
@m.should_not be_changed
|
175
|
-
ImmortalModel.first.should == @m
|
176
|
-
end
|
177
|
-
|
178
|
-
it "should consider an Many-to-many association with through as deleted when the join is deleted." do
|
179
|
-
@n = ImmortalNode.create! title: 'testing association'
|
180
|
-
@join = ImmortalJoin.create! immortal_model: @m, immortal_node: @n
|
181
|
-
|
182
|
-
@m.nodes.count.should == 1
|
183
|
-
@n.models.count.should == 1
|
184
|
-
|
185
|
-
@join.destroy
|
186
|
-
|
187
|
-
@m.nodes.count.should == 0
|
188
|
-
@n.models.count.should == 0
|
189
|
-
end
|
190
|
-
|
191
|
-
it "should only immortally delete scoped associations, NOT ALL RECORDS" do
|
192
|
-
n1 = ImmortalNode.create! title: 'testing association 1'
|
193
|
-
j1 = ImmortalJoin.create! immortal_model: @m, immortal_node: n1
|
194
|
-
|
195
|
-
n2 = ImmortalNode.create! title: 'testing association 2'
|
196
|
-
j2 = ImmortalJoin.create! immortal_model: @m, immortal_node: n2
|
197
|
-
|
198
|
-
n3 = ImmortalNode.create! title: 'testing association 3'
|
199
|
-
j3 = ImmortalJoin.create! immortal_node: n3
|
200
|
-
|
201
|
-
@m.destroy
|
202
|
-
|
203
|
-
[n1,n2,j1,j2].all? {|r| r.reload.deleted?}.should be_true
|
204
|
-
[n3,j3].all? {|r| !r.reload.deleted?}.should be_true
|
205
|
-
end
|
206
|
-
|
207
|
-
it "should properly generate joins" do
|
208
|
-
join_sql1 = 'INNER JOIN "immortal_joins" ON "immortal_joins"."immortal_node_id" = "immortal_nodes"."id"'
|
209
|
-
join_sql2 = 'INNER JOIN "immortal_models" ON "immortal_models"."id" = "immortal_joins"."immortal_model_id"'
|
210
|
-
generated_sql = ImmortalNode.joins(:immortal_models).to_sql
|
211
|
-
generated_sql.should include(join_sql1)
|
212
|
-
generated_sql.should include(join_sql2)
|
213
|
-
end
|
214
|
-
|
215
|
-
it "should reload immortal polymorphic associations using default reader" do
|
216
|
-
node = ImmortalNode.create! title: 'testing association 1'
|
217
|
-
target_1 = ImmortalSomeTarget.create! title: 'target 1'
|
218
|
-
target_2 = ImmortalSomeOtherTarget.create! title: 'target 2'
|
219
|
-
|
220
|
-
node.target.should be_nil
|
221
|
-
node.target = target_1
|
222
|
-
node.target.should == target_1
|
223
|
-
|
224
|
-
node.target_id = target_2.id
|
225
|
-
node.target_type = target_2.class.name
|
226
|
-
|
227
|
-
target_2.destroy
|
228
|
-
node.target.should be_nil
|
229
|
-
end
|
230
|
-
|
231
|
-
it "should reload immortal polymorphic associations using deleted reader" do
|
232
|
-
#setup
|
233
|
-
node = ImmortalNode.create! title: 'testing association 1'
|
234
|
-
target_1 = ImmortalSomeTarget.create! title: 'target 1'
|
235
|
-
target_2 = ImmortalSomeOtherTarget.create! title: 'target 2'
|
236
|
-
|
237
|
-
#confirm initial state
|
238
|
-
node.target.should be_nil
|
239
|
-
|
240
|
-
#load target & confirm
|
241
|
-
node.target = target_1
|
242
|
-
node.target.should == target_1
|
243
|
-
|
244
|
-
#switch target indirectly
|
245
|
-
node.target_id = target_2.id
|
246
|
-
node.target_type = target_2.class.name
|
247
|
-
|
248
|
-
#don't assign directly and destroy new target
|
249
|
-
target_2.destroy
|
250
|
-
|
251
|
-
#Ask for deleted target (or not deleted). Will NOT cache
|
252
|
-
# Run this before default accessor to test scope has been reset.
|
253
|
-
node.target_with_deleted.should == target_2
|
254
|
-
|
255
|
-
#Respect what's expected
|
256
|
-
node.target.should be_nil
|
257
|
-
|
258
|
-
#Ask only for deleted target. Will NOT cache
|
259
|
-
node.target_only_deleted.should == target_2
|
260
|
-
|
261
|
-
#Confirm we haven't invaded the target namespace
|
262
|
-
node.target.should be_nil
|
263
|
-
end
|
264
|
-
|
265
|
-
it "should reload immortal polymorphic associations using deleted reader (direct assignment)" do
|
266
|
-
#setup
|
267
|
-
node = ImmortalNode.create! title: 'testing association 1'
|
268
|
-
target_1 = ImmortalSomeTarget.create! title: 'target 1'
|
269
|
-
target_2 = ImmortalSomeOtherTarget.create! title: 'target 2'
|
270
|
-
|
271
|
-
#confirm initial state
|
272
|
-
node.target.should be_nil
|
273
|
-
|
274
|
-
#load target & confirm
|
275
|
-
node.target = target_1
|
276
|
-
node.target.should == target_1
|
277
|
-
|
278
|
-
#switch target directly
|
279
|
-
node.target = target_2
|
280
|
-
|
281
|
-
node.target.should == target_2
|
282
|
-
node.target_with_deleted.should == target_2
|
283
|
-
|
284
|
-
#don't assign directly and destroy new target
|
285
|
-
target_2.destroy
|
286
|
-
|
287
|
-
#Respect what's expected
|
288
|
-
node.target(true).should be_nil
|
289
|
-
|
290
|
-
#Ask for deleted target (or not deleted). Will NOT cache
|
291
|
-
node.target_with_deleted.should == target_2
|
292
|
-
|
293
|
-
#Confirm we haven't invaded the target namespace
|
294
|
-
node.target.should be_nil
|
295
|
-
end
|
296
|
-
|
297
|
-
it "deleted readers should respect staleness" do
|
298
|
-
#setup
|
299
|
-
node = ImmortalNode.create! title: 'testing association 1'
|
300
|
-
target_1 = ImmortalSomeTarget.create! title: 'target 1'
|
301
|
-
target_2 = ImmortalSomeOtherTarget.create! title: 'target 2'
|
302
|
-
|
303
|
-
#confirm initial state
|
304
|
-
node.target.should be_nil
|
305
|
-
node.target_with_deleted.should be_nil
|
306
|
-
node.target_only_deleted.should be_nil
|
307
|
-
|
308
|
-
#load target & confirm
|
309
|
-
node.target = target_1
|
310
|
-
node.target.should == target_1
|
311
|
-
node.target_with_deleted.should == target_1
|
312
|
-
node.target_only_deleted.should be_nil
|
313
|
-
|
314
|
-
#switch target directly
|
315
|
-
node.target = target_2
|
316
|
-
|
317
|
-
node.target.should == target_2
|
318
|
-
node.target_with_deleted.should == target_2
|
319
|
-
|
320
|
-
#don't assign directly and destroy new target
|
321
|
-
target_2.destroy
|
322
|
-
|
323
|
-
#Respect what's expected
|
324
|
-
node.target(true).should be_nil
|
325
|
-
|
326
|
-
#Ask for deleted target (or not deleted).
|
327
|
-
node.target_with_deleted.should == target_2
|
328
|
-
node.target_only_deleted.should == target_2
|
329
|
-
|
330
|
-
#Confirm we haven't invaded the target namespace
|
331
|
-
node.target.should be_nil
|
332
|
-
|
333
|
-
node.target_id = target_1.id
|
334
|
-
node.target_type = target_1.class.name
|
335
|
-
node.target.should == target_1
|
336
|
-
node.target_with_deleted.should == target_1
|
337
|
-
node.target_only_deleted.should be_nil
|
338
|
-
end
|
339
|
-
|
340
|
-
it "should not unscope associations when using with_deleted scope" do
|
341
|
-
m1 = ImmortalModel.create! title: 'previously created model'
|
342
|
-
n1 = ImmortalNode.create! title: 'previously created association'
|
343
|
-
ImmortalJoin.create! immortal_model: m1, immortal_node: n1
|
344
|
-
|
345
|
-
@n = ImmortalNode.create! title: 'testing association'
|
346
|
-
@join = ImmortalJoin.create! immortal_model: @m, immortal_node: @n
|
347
|
-
|
348
|
-
@join.destroy
|
349
|
-
|
350
|
-
@m.nodes.count.should == 0
|
351
|
-
@n.joins.count.should == 0
|
352
|
-
|
353
|
-
@m.nodes.count_with_deleted.should == 1
|
354
|
-
@n.joins.count_with_deleted.should == 1
|
355
|
-
end
|
356
|
-
|
357
|
-
it "should not unscope associations when using only_deleted scope" do
|
358
|
-
m1 = ImmortalModel.create! title: 'previously created model'
|
359
|
-
n1 = ImmortalNode.create! title: 'previously created association'
|
360
|
-
ImmortalJoin.create! immortal_model: m1, immortal_node: n1
|
361
|
-
|
362
|
-
@n = ImmortalNode.create! title: 'testing association'
|
363
|
-
@join = ImmortalJoin.create! immortal_model: @m, immortal_node: @n
|
364
|
-
|
365
|
-
@join.destroy
|
366
|
-
|
367
|
-
@m.nodes.count.should == 0
|
368
|
-
@n.joins.count.should == 0
|
369
|
-
|
370
|
-
@m.nodes.count_only_deleted
|
371
|
-
@m.nodes.count_only_deleted.should == 1
|
372
|
-
@n.joins.count_only_deleted.should == 1
|
373
|
-
end
|
374
|
-
|
375
|
-
it 'warn when deleted column is nullable' do
|
376
|
-
Kernel.should_receive(:warn)
|
377
|
-
|
378
|
-
class ImmortalNullableDeleted
|
379
|
-
include Immortal
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,145 +0,0 @@
|
|
1
|
-
Bundler.require(:default, :development)
|
2
|
-
require 'rspec'
|
3
|
-
require File.expand_path("../../lib/immortal", __FILE__)
|
4
|
-
require 'active_record'
|
5
|
-
require 'sqlite3'
|
6
|
-
require 'logger'
|
7
|
-
|
8
|
-
RSpec.configure do |config|
|
9
|
-
config.before(:each) do
|
10
|
-
ActiveRecord::Base.connection.execute('delete from immortal_models')
|
11
|
-
end
|
12
|
-
|
13
|
-
config.after(:all) do
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
19
|
-
ActiveRecord::Base.logger = Logger.new(STDOUT) if ENV['DEBUG']
|
20
|
-
|
21
|
-
old_stdout = $stdout
|
22
|
-
$stdout = StringIO.new
|
23
|
-
|
24
|
-
begin
|
25
|
-
ActiveRecord::Schema.define do
|
26
|
-
create_table :immortal_models do |t|
|
27
|
-
t.string :title
|
28
|
-
t.integer :value
|
29
|
-
t.boolean :deleted, default: false, null: false
|
30
|
-
t.timestamps
|
31
|
-
end
|
32
|
-
create_table :immortal_joins do |t|
|
33
|
-
t.integer :immortal_model_id
|
34
|
-
t.integer :immortal_node_id
|
35
|
-
t.boolean :deleted, default: false, null: false
|
36
|
-
t.timestamps
|
37
|
-
end
|
38
|
-
create_table :immortal_nodes do |t|
|
39
|
-
t.integer :target_id
|
40
|
-
t.string :target_type
|
41
|
-
t.string :title
|
42
|
-
t.integer :value
|
43
|
-
t.boolean :deleted, default: false, null: false
|
44
|
-
t.timestamps
|
45
|
-
end
|
46
|
-
|
47
|
-
create_table :immortal_some_targets do |t|
|
48
|
-
t.string :title
|
49
|
-
t.boolean :deleted, default: false, null: false
|
50
|
-
t.timestamps
|
51
|
-
end
|
52
|
-
|
53
|
-
create_table :immortal_some_other_targets do |t|
|
54
|
-
t.string :title
|
55
|
-
t.boolean :deleted, default: false, null: false
|
56
|
-
t.timestamps
|
57
|
-
end
|
58
|
-
|
59
|
-
create_table :immortal_nullable_deleteds do |t|
|
60
|
-
t.string :title
|
61
|
-
t.boolean :deleted, default: false
|
62
|
-
t.timestamps
|
63
|
-
end
|
64
|
-
end
|
65
|
-
ensure
|
66
|
-
$stdout = old_stdout
|
67
|
-
end
|
68
|
-
|
69
|
-
class ImmortalJoin < ActiveRecord::Base
|
70
|
-
include Immortal
|
71
|
-
|
72
|
-
belongs_to :immortal_model
|
73
|
-
belongs_to :immortal_node, dependent: :destroy
|
74
|
-
end
|
75
|
-
|
76
|
-
class ImmortalNode < ActiveRecord::Base
|
77
|
-
include Immortal
|
78
|
-
|
79
|
-
has_many :immortal_joins
|
80
|
-
has_many :immortal_models, through: :immortal_joins
|
81
|
-
|
82
|
-
has_many :joins, class_name: 'ImmortalJoin'
|
83
|
-
has_many :models, through: :joins, source: :immortal_model
|
84
|
-
|
85
|
-
belongs_to :target, polymorphic: true
|
86
|
-
end
|
87
|
-
|
88
|
-
class ImmortalSomeTarget < ActiveRecord::Base
|
89
|
-
include Immortal
|
90
|
-
|
91
|
-
has_many :immortal_nodes, as: :target
|
92
|
-
end
|
93
|
-
|
94
|
-
class ImmortalSomeOtherTarget < ActiveRecord::Base
|
95
|
-
include Immortal
|
96
|
-
|
97
|
-
has_many :immortal_nodes, as: :target
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
class ImmortalModel < ActiveRecord::Base
|
102
|
-
include Immortal
|
103
|
-
|
104
|
-
has_many :immortal_nodes, through: :immortal_joins, dependent: :destroy
|
105
|
-
has_many :immortal_joins, dependent: :delete_all
|
106
|
-
|
107
|
-
has_many :joins, class_name: 'ImmortalJoin', dependent: :delete_all
|
108
|
-
has_many :nodes, through: :joins, source: :immortal_node, dependent: :destroy
|
109
|
-
|
110
|
-
attr_accessor :before_d, :after_d, :before_u, :after_u, :after_commit, :before_return
|
111
|
-
|
112
|
-
before_destroy :set_before
|
113
|
-
after_destroy :set_after
|
114
|
-
before_update :set_before_update
|
115
|
-
after_update :set_after_update
|
116
|
-
after_commit :set_after_commit, on: :destroy
|
117
|
-
|
118
|
-
private
|
119
|
-
|
120
|
-
def set_before
|
121
|
-
@before_d = true
|
122
|
-
@before_return
|
123
|
-
end
|
124
|
-
|
125
|
-
def set_after
|
126
|
-
@after_d = true
|
127
|
-
end
|
128
|
-
|
129
|
-
def set_after_update
|
130
|
-
@after_u = true
|
131
|
-
end
|
132
|
-
|
133
|
-
def set_after_commit
|
134
|
-
@after_commit = true
|
135
|
-
end
|
136
|
-
|
137
|
-
def set_before_update
|
138
|
-
@before_u = true
|
139
|
-
end
|
140
|
-
|
141
|
-
end
|
142
|
-
|
143
|
-
class ImmortalNullableDeleted < ActiveRecord::Base
|
144
|
-
end
|
145
|
-
|