kakurenbo 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 346d73c09028575300edf7ae7d3f5e3e67eb4a26
4
- data.tar.gz: 29a988182dbcf85583edbe4ce740d15bc736c0ac
3
+ metadata.gz: 1db2fcbe670f950ac46f450c5365921042ec298b
4
+ data.tar.gz: b52de24c10f252966d25f629b86679142fcb0024
5
5
  SHA512:
6
- metadata.gz: bb22422cb2a04879d74e6387b2ac481678813e7f621a37961b35a452d434194f123fa4c64a748bd22de44a18543c04d11a035891dfdb243228e1e156612163f8
7
- data.tar.gz: f6013d0b2a5373f3df8c17b5cd3d9783fd003fe1bde2162b3c04ebe3d45acf86815e28be39ac9b722307f6257f4624cb524d35297cb1001c749630914e0b0e0b
6
+ metadata.gz: ad49f6368d5bd864abbe3847ceeae2db12f0df1a55977fc3de36b94758ea6ce561be9e60504e4218f40afaba2c29b174cc1122fc71bc8c7f936fa716e664fbec
7
+ data.tar.gz: 7f198fd7fb0ab7a0cd41e17ffcffe8f2c3e8464759d0db95cc7334c79202765f57195afdbd628bb8a1a3311f8021e3122d69e0b89b895db26121b97498933575
data/README.md CHANGED
@@ -31,6 +31,16 @@ _Kakurenbo provides `acts_as_paranoid` method for compatibility._
31
31
 
32
32
  ``` ruby
33
33
  model.destroy
34
+
35
+ # This is usable, too.
36
+ Model.destroy(id)
37
+ Model.destroy([id1,id2,id3])
38
+ ```
39
+
40
+ when want without callbacks.
41
+
42
+ ``` ruby
43
+ model.delete
34
44
  ```
35
45
 
36
46
  ### restore a record
@@ -40,6 +50,7 @@ model.restore!
40
50
 
41
51
  # This is usable, too.
42
52
  Model.restore(id)
53
+ Model.restore([id1,id2,id3])
43
54
  ```
44
55
 
45
56
  When restore, call restore callbacks.`before_restore` `after_restore`
@@ -13,7 +13,7 @@ module Kakurenbo
13
13
  next unless column_names.include?('deleted_at')
14
14
  remodel_as_soft_delete
15
15
  rescue
16
- # When migrate.
16
+ # When exec first db:migrate and db:migrate:reset.
17
17
  end
18
18
  }
19
19
  super
@@ -31,8 +31,8 @@ module Kakurenbo
31
31
  )
32
32
 
33
33
  unless paranoid?
34
- alias_method :delete!, :delete
35
- alias_method :destroy!, :destroy
34
+ alias_method :hard_delete!, :delete
35
+ alias_method :hard_destroy!, :destroy
36
36
 
37
37
  class_attribute :kakurenbo_column
38
38
  self.kakurenbo_column = options[:column]
@@ -5,6 +5,7 @@ module Kakurenbo
5
5
  base_class.extend ClassMethods
6
6
  base_class.extend Callbacks
7
7
  base_class.extend Scopes
8
+ base_class.extend Aliases
8
9
  end
9
10
 
10
11
  module ClassMethods
@@ -12,12 +13,23 @@ module Kakurenbo
12
13
  true
13
14
  end
14
15
 
15
- # Restore models.
16
+ # Destroy model(s).
16
17
  #
17
- # @param id [Array or Integer] id or ids.
18
+ # @param id [Array<Integer> or Integer] id or ids
19
+ def destroy(id)
20
+ transaction do
21
+ where(:id => id).each{|m| m.destroy}
22
+ end
23
+ end
24
+
25
+ # Restore model(s).
26
+ #
27
+ # @param id [Array<Integer> or Integer] id or ids.
18
28
  # @param options [Hash] options(same restore of instance methods.)
19
- def restore(id, options = {})
20
- only_deleted.where(:id => id).each{|m| m.restore!(options)}
29
+ def restore(id, options = {:recursive => true})
30
+ transaction do
31
+ only_deleted.where(:id => id).each{|m| m.restore!(options)}
32
+ end
21
33
  end
22
34
  end
23
35
 
@@ -45,6 +57,17 @@ module Kakurenbo
45
57
  end
46
58
  end
47
59
 
60
+ module Aliases
61
+ def self.extended(base_class)
62
+ base_class.instance_eval {
63
+ alias_method :delete!, :hard_delete!
64
+ alias_method :deleted?, :destroyed?
65
+ alias_method :restore, :restore!
66
+ alias_method :recover, :restore!
67
+ }
68
+ end
69
+ end
70
+
48
71
  def delete
49
72
  return if new_record? or destroyed?
50
73
  update_column kakurenbo_column, current_time_from_proper_timezone
@@ -52,16 +75,22 @@ module Kakurenbo
52
75
 
53
76
  def destroy
54
77
  return if destroyed?
55
- with_transaction_returning_status {
78
+ with_transaction_returning_status do
56
79
  destroy_at = current_time_from_proper_timezone
57
80
  run_callbacks(:destroy){ update_column kakurenbo_column, destroy_at }
58
- }
81
+ end
82
+ end
83
+
84
+ def destroy!
85
+ with_transaction_returning_status do
86
+ hard_destroy_associated_records
87
+ self.reload.hard_destroy!
88
+ end
59
89
  end
60
90
 
61
91
  def destroyed?
62
92
  !send(kakurenbo_column).nil?
63
93
  end
64
- alias_method :deleted?, :destroyed?
65
94
 
66
95
  def kakurenbo_column
67
96
  self.class.kakurenbo_column
@@ -77,22 +106,32 @@ module Kakurenbo
77
106
  # defaults: {
78
107
  # recursive: true
79
108
  # }
80
- def restore!(options = {})
81
- options.reverse_merge!(
82
- :recursive => true
83
- )
84
-
85
- with_transaction_returning_status {
109
+ def restore!(options = {:recursive => true})
110
+ with_transaction_returning_status do
86
111
  run_callbacks(:restore) do
87
112
  parent_deleted_at = send(kakurenbo_column)
88
113
  update_column kakurenbo_column, nil
89
114
  restore_associated_records(parent_deleted_at) if options[:recursive]
90
115
  end
91
- }
116
+ end
92
117
  end
93
- alias_method :restore, :restore!
94
118
 
95
119
  private
120
+ # get recoreds of association.
121
+ #
122
+ # @param association [ActiveRecord::Associations] association.
123
+ # @return [Array or CollectionProxy] records.
124
+ def associated_records(association)
125
+ resource = send(association.name)
126
+ if resource.nil?
127
+ []
128
+ elsif association.collection?
129
+ resource.with_deleted
130
+ else
131
+ [resource]
132
+ end
133
+ end
134
+
96
135
  # Calls the given block once for each dependent destroy records.
97
136
  # @note Only call the class of paranoid.
98
137
  #
@@ -102,16 +141,14 @@ module Kakurenbo
102
141
  next unless association.options[:dependent] == :destroy
103
142
  next unless association.klass.paranoid?
104
143
 
105
- resource = send(association.name)
106
- next if resource.nil?
107
-
108
- if association.collection?
109
- resource = resource.only_deleted
110
- else
111
- resource = (resource.destroyed?) ? [resource] : []
112
- end
144
+ associated_records(association).each &block
145
+ end
146
+ end
113
147
 
114
- resource.each &block
148
+ # Hard-Destroy associated records.
149
+ def hard_destroy_associated_records
150
+ each_dependent_destroy_records do |record|
151
+ record.destroy!
115
152
  end
116
153
  end
117
154
 
@@ -121,6 +158,7 @@ module Kakurenbo
121
158
  # @param parent_deleted_at [Time] The time when parent was deleted.
122
159
  def restore_associated_records(parent_deleted_at)
123
160
  each_dependent_destroy_records do |record|
161
+ next unless record.destroyed?
124
162
  next unless parent_deleted_at <= record.send(kakurenbo_column)
125
163
  record.restore!
126
164
  end
@@ -1,3 +1,3 @@
1
1
  module Kakurenbo
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -0,0 +1,270 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kakurenbo::SoftDeleteCore do
4
+ create_temp_table(:parent_models) { |t| t.integer :child_id; t.datetime :deleted_at }
5
+ create_temp_table(:normal_child_models) { |t| t.integer :parent_model_id }
6
+ create_temp_table(:paranoid_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
7
+ create_temp_table(:paranoid_single_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
8
+
9
+ before :each do
10
+ class NormalChildModel < ActiveRecord::Base; end
11
+ class ParanoidChildModel < ActiveRecord::Base; end
12
+ class ParanoidSingleChildModel < ActiveRecord::Base; end
13
+ class ParentModel < ActiveRecord::Base
14
+ has_many :normal_child_models, :dependent => :destroy
15
+ has_many :paranoid_child_models, :dependent => :destroy
16
+
17
+ has_one :paranoid_single_child_model, :dependent => :destroy
18
+ belongs_to :child, :class_name => :ParanoidSingleChildModel, :dependent => :destroy
19
+ end
20
+ end
21
+
22
+ after :each do
23
+ Object.class_eval do
24
+ remove_const :NormalChildModel
25
+ remove_const :ParanoidChildModel
26
+ remove_const :ParanoidSingleChildModel
27
+ remove_const :ParentModel
28
+ end
29
+ end
30
+
31
+ describe 'NormalChildModel' do
32
+ before :each do
33
+ @parent = ParentModel.create!
34
+ @first = @parent.normal_child_models.create!
35
+ @second = @parent.normal_child_models.create!
36
+
37
+ @hitori = NormalChildModel.create!
38
+ end
39
+
40
+ context 'when parent be destroyed' do
41
+ it 'destroy children who parent has.' do
42
+ expect{@parent.destroy}.to change(NormalChildModel, :count).by(-2)
43
+ end
44
+
45
+ it 'not destroy children who parent does not have.' do
46
+ @parent.destroy
47
+ expect(@hitori.reload.destroyed?).to be_false
48
+ end
49
+ end
50
+ end
51
+
52
+ describe 'ParanoidChildModel' do
53
+ before :each do
54
+ @parent = ParentModel.create!
55
+ @first = @parent.paranoid_child_models.create!
56
+ @second = @parent.paranoid_child_models.create!
57
+ @third = @parent.paranoid_child_models.create!
58
+
59
+ @hitori = ParanoidChildModel.create!
60
+ end
61
+
62
+ context 'when parent be destroyed' do
63
+ it 'destroy children who parent has.' do
64
+ expect{@parent.destroy}.to change(ParanoidChildModel, :count).by(-3)
65
+ expect(@first.reload.destroyed?).to be_true
66
+ expect(@second.reload.destroyed?).to be_true
67
+ expect(@third.reload.destroyed?).to be_true
68
+ end
69
+
70
+ it 'not destroy children who parent does not have.' do
71
+ @parent.destroy
72
+ expect(@hitori.reload.destroyed?).to be_false
73
+ end
74
+ end
75
+
76
+ context 'when parent be restored' do
77
+ before :each do
78
+ @parent.destroy
79
+ @hitori.destroy
80
+ end
81
+
82
+ it 'restore children who parent has.' do
83
+ expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(3)
84
+ expect(@first.reload.destroyed?).to be_false
85
+ expect(@second.reload.destroyed?).to be_false
86
+ expect(@third.reload.destroyed?).to be_false
87
+ end
88
+
89
+ it 'not restore children who parent does not have.' do
90
+ @parent.restore!
91
+ expect(@hitori.reload.destroyed?).to be_true
92
+ end
93
+ end
94
+
95
+ context 'when delete child before parent was deleted' do
96
+ before :each do
97
+ # First, delete child.
98
+ delete_at = 1.second.ago
99
+ Time.stub(:now).and_return(delete_at)
100
+ @first.destroy
101
+
102
+ # Next, delete parent.
103
+ Time.unstub(:now)
104
+ @parent.destroy
105
+ end
106
+
107
+ it 'not restore child who deleted before parent was deleted' do
108
+ expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(2)
109
+ expect(@first.reload.destroyed?).to be_true
110
+ end
111
+
112
+ it 'restore children who deleted after parent was deleted' do
113
+ expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(2)
114
+ expect(@second.reload.destroyed?).to be_false
115
+ expect(@third.reload.destroyed?).to be_false
116
+ end
117
+ end
118
+ end
119
+
120
+ describe 'ParanoidSingleChildModel(has_one)' do
121
+ before :each do
122
+ @parent = ParentModel.create!
123
+ @first = ParanoidSingleChildModel.create!(parent_model_id: @parent.id)
124
+
125
+ @hitori = ParanoidSingleChildModel.create!
126
+ end
127
+
128
+ context 'when parent be destroyed' do
129
+ it 'destroy child who parent has.' do
130
+ expect{@parent.destroy}.to change(ParanoidSingleChildModel, :count).by(-1)
131
+ expect(@first.reload.destroyed?).to be_true
132
+ end
133
+
134
+ it 'not destroy child who parent does not have.' do
135
+ @parent.destroy
136
+ expect(@hitori.reload.destroyed?).to be_false
137
+ end
138
+ end
139
+
140
+ context 'when parent be restored' do
141
+ before :each do
142
+ @parent.destroy
143
+ @hitori.destroy
144
+ end
145
+
146
+ it 'restore child who parent has.' do
147
+ expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(1)
148
+ expect(@first.reload.destroyed?).to be_false
149
+ end
150
+
151
+ it 'not restore child who parent does not have.' do
152
+ @parent.restore
153
+ expect(@hitori.reload.destroyed?).to be_true
154
+ end
155
+ end
156
+
157
+ context 'when delete child before parent was deleted' do
158
+ before :each do
159
+ # First, delete child.
160
+ delete_at = 1.second.ago
161
+ Time.stub(:now).and_return(delete_at)
162
+ @first.destroy
163
+
164
+ # Next, delete parent.
165
+ Time.unstub(:now)
166
+ @parent.destroy
167
+ end
168
+
169
+ it 'not restore child who deleted before parent was deleted' do
170
+ expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(0)
171
+ expect(@first.reload.destroyed?).to be_true
172
+ end
173
+ end
174
+ end
175
+
176
+ describe 'ParanoidSingleChildModel(belongs_to)' do
177
+ before :each do
178
+ @first = ParanoidSingleChildModel.create!
179
+ @parent = ParentModel.create!(child_id: @first.id)
180
+
181
+ @hitori = ParanoidSingleChildModel.create!
182
+ end
183
+
184
+ context 'when parent be destroyed' do
185
+ it 'destroy child who parent has.' do
186
+ expect{@parent.destroy}.to change(ParanoidSingleChildModel, :count).by(-1)
187
+ expect(@first.reload.destroyed?).to be_true
188
+ end
189
+
190
+ it 'not destroy child who parent does not have.' do
191
+ @parent.destroy
192
+ expect(@hitori.reload.destroyed?).to be_false
193
+ end
194
+ end
195
+
196
+ context 'when parent be restored' do
197
+ before :each do
198
+ @parent.destroy
199
+ @hitori.destroy
200
+ end
201
+
202
+ it 'restore child who parent has.' do
203
+ expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(1)
204
+ expect(@first.reload.destroyed?).to be_false
205
+ end
206
+
207
+ it 'not restore child who parent does not have.' do
208
+ @parent.restore
209
+ expect(@hitori.reload.destroyed?).to be_true
210
+ end
211
+ end
212
+
213
+ context 'when delete child before parent was deleted' do
214
+ before :each do
215
+ # First, delete child.
216
+ delete_at = 1.second.ago
217
+ Time.stub(:now).and_return(delete_at)
218
+ @first.destroy
219
+
220
+ # Next, delete parent.
221
+ Time.unstub(:now)
222
+ @parent.destroy
223
+ end
224
+
225
+ it 'not restore child who deleted before parent was deleted' do
226
+ expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(0)
227
+ expect(@first.reload.destroyed?).to be_true
228
+ end
229
+ end
230
+ end
231
+
232
+ describe 'ChildModels' do
233
+ before :each do
234
+ @parent = ParentModel.create!
235
+
236
+ @normal_first = @parent.normal_child_models.create!
237
+ @normal_second = @parent.normal_child_models.create!
238
+
239
+ @paranoid_first = @parent.paranoid_child_models.create!
240
+ @paranoid_second = @parent.paranoid_child_models.create!
241
+
242
+ @single_first = ParanoidSingleChildModel.create!(parent_model_id: @parent.id)
243
+
244
+ @normal_hitori = NormalChildModel.create!
245
+ @paranoid_hitori = ParanoidChildModel.create!
246
+ @single_hitori = ParanoidSingleChildModel.create!
247
+ end
248
+
249
+ context 'when parent be hard-destroyed' do
250
+ it 'hard-destroy normal children who parent has.' do
251
+ expect{@parent.destroy!}.to change(NormalChildModel, :count).by(-2)
252
+ end
253
+
254
+ it 'hard-destroy paranoid children who parent has.' do
255
+ expect{@parent.destroy!}.to change{ParanoidChildModel.with_deleted.count}.by(-2)
256
+ end
257
+
258
+ it 'hard-destroy paranoid single child who parent has.' do
259
+ expect{@parent.destroy!}.to change{ParanoidSingleChildModel.with_deleted.count}.by(-1)
260
+ end
261
+
262
+ it 'not destroy child who parent does not have.' do
263
+ @parent.destroy!
264
+ expect(@normal_hitori.reload.destroyed?).to be_false
265
+ expect(@paranoid_hitori.reload.destroyed?).to be_false
266
+ expect(@single_hitori.reload.destroyed?).to be_false
267
+ end
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kakurenbo::SoftDeleteCore::Callbacks do
4
+ create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
5
+
6
+ before :each do
7
+ class ParanoidModel < ActiveRecord::Base; end
8
+ end
9
+
10
+ after :each do
11
+ Object.class_eval{ remove_const :ParanoidModel }
12
+ end
13
+
14
+ context 'when run callback of restore' do
15
+ before :each do
16
+ @callback_model = ParanoidModel.create!
17
+ end
18
+
19
+ after :each do
20
+ @callback_model.run_callbacks(:restore)
21
+ end
22
+
23
+ it 'call before_restore.' do
24
+ ParanoidModel.before_restore :before_restore_callback
25
+ @callback_model.should_receive(:before_restore_callback).once
26
+ end
27
+
28
+ it 'call around_restore.' do
29
+ ParanoidModel.around_restore :around_restore_callback
30
+ @callback_model.should_receive(:around_restore_callback).once
31
+ end
32
+
33
+ it 'call after_restore.' do
34
+ ParanoidModel.after_restore :after_restore_callback
35
+ @callback_model.should_receive(:after_restore_callback).once
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,229 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kakurenbo::SoftDeleteCore do
4
+ create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
5
+
6
+ before :each do
7
+ class ParanoidModel < ActiveRecord::Base; end
8
+ end
9
+
10
+ after :each do
11
+ Object.class_eval{ remove_const :ParanoidModel }
12
+ end
13
+
14
+ describe 'Instance of paranoid model' do
15
+ before :each do
16
+ @model = ParanoidModel.create!
17
+ end
18
+
19
+ context 'when delete' do
20
+ it 'soft-delete model.' do
21
+ expect{
22
+ @model.delete
23
+ }.to change(ParanoidModel, :count).by(-1)
24
+ end
25
+
26
+ it 'not hard-delete model.' do
27
+ expect{
28
+ @model.delete
29
+ }.to change{
30
+ ParanoidModel.all.with_deleted.count
31
+ }.by(0)
32
+ end
33
+
34
+ it 'call callbacks nothing.' do
35
+ ParanoidModel.before_destroy :before_destroy_callback
36
+ ParanoidModel.after_destroy :after_destroy_callback
37
+ ParanoidModel.after_commit :after_commit_callback
38
+
39
+ @model.should_receive(:before_destroy_callback).exactly(0).times
40
+ @model.should_receive(:after_destroy_callback).exactly(0).times
41
+ @model.should_receive(:after_commit_callback).exactly(0).times
42
+
43
+ @model.delete
44
+ end
45
+
46
+ it 'not call callbacks other.' do
47
+ ParanoidModel.before_update :before_update_callback
48
+ ParanoidModel.before_save :before_save_callback
49
+ ParanoidModel.validate :validate_callback
50
+
51
+ @model.should_receive(:before_update_callback).exactly(0).times
52
+ @model.should_receive(:before_save_callback).exactly(0).times
53
+ @model.should_receive(:validate_callback).exactly(0).times
54
+
55
+ @model.delete
56
+ end
57
+ end
58
+
59
+ context 'when delete!' do
60
+ it 'hard-delete model.' do
61
+ expect{
62
+ @model.delete!
63
+ }.to change{
64
+ ParanoidModel.all.with_deleted.count
65
+ }.by(-1)
66
+ end
67
+ end
68
+
69
+ context 'when destroy(class method)' do
70
+ before :each do
71
+ @model2 = ParanoidModel.create!
72
+ end
73
+
74
+ it 'with id, destroy model.' do
75
+ expect{
76
+ ParanoidModel.destroy(@model.id)
77
+ }.to change(ParanoidModel, :count).by(-1)
78
+
79
+ expect(@model.reload.destroyed?).to be_true
80
+ end
81
+
82
+ it 'with ids, destroy models.' do
83
+ expect{
84
+ ParanoidModel.destroy([@model.id, @model2.id])
85
+ }.to change(ParanoidModel, :count).by(-2)
86
+
87
+ expect(@model.reload.destroyed?).to be_true
88
+ expect(@model2.reload.destroyed?).to be_true
89
+ end
90
+ end
91
+
92
+ context 'when destroy(instance method)' do
93
+ it 'soft-delete model.' do
94
+ expect{
95
+ @model.destroy
96
+ }.to change(ParanoidModel, :count).by(-1)
97
+ end
98
+
99
+ it 'not hard-delete model.' do
100
+ expect{
101
+ @model.destroy
102
+ }.to change{
103
+ ParanoidModel.all.with_deleted.count
104
+ }.by(0)
105
+ end
106
+
107
+ it 'call callbacks of destroy.' do
108
+ ParanoidModel.before_destroy :before_destroy_callback
109
+ ParanoidModel.after_destroy :after_destroy_callback
110
+ ParanoidModel.after_commit :after_commit_callback
111
+
112
+ @model.should_receive(:before_destroy_callback).once
113
+ @model.should_receive(:after_destroy_callback).once
114
+ @model.should_receive(:after_commit_callback).once.and_return(true)
115
+
116
+ @model.destroy
117
+ end
118
+
119
+ it 'not call callbacks without destroy.' do
120
+ ParanoidModel.before_update :before_update_callback
121
+ ParanoidModel.before_save :before_save_callback
122
+ ParanoidModel.validate :validate_callback
123
+
124
+ @model.should_receive(:before_update_callback).exactly(0).times
125
+ @model.should_receive(:before_save_callback).exactly(0).times
126
+ @model.should_receive(:validate_callback).exactly(0).times
127
+
128
+ @model.destroy
129
+ end
130
+ end
131
+
132
+ context 'when destroy!' do
133
+ it 'hard-delete model.' do
134
+ expect{
135
+ @model.destroy!
136
+ }.to change{
137
+ ParanoidModel.all.with_deleted.count
138
+ }.by(-1)
139
+ end
140
+ end
141
+
142
+ context 'when destroyed?' do
143
+ it 'false if model not destroyed.' do
144
+ expect(@model.destroyed?).to be_false
145
+ end
146
+
147
+ it 'false if model destroyed.' do
148
+ @model.destroy
149
+ expect(@model.destroyed?).to be_true
150
+ end
151
+
152
+ it 'alias deleted? to destroyed?' do
153
+ expect(@model.deleted?).to be_false
154
+ end
155
+ end
156
+
157
+ context 'when restore(class method)' do
158
+ before :each do
159
+ @model.destroy
160
+
161
+ @model2 = ParanoidModel.create!
162
+ @model2.destroy
163
+ end
164
+
165
+ it 'with id, restore model.' do
166
+ expect{
167
+ ParanoidModel.restore(@model.id)
168
+ }.to change(ParanoidModel, :count).by(1)
169
+
170
+ expect(@model.reload.destroyed?).to be_false
171
+ end
172
+
173
+ it 'with ids, restore models.' do
174
+ expect{
175
+ ParanoidModel.restore([@model.id, @model2.id])
176
+ }.to change(ParanoidModel, :count).by(2)
177
+
178
+ expect(@model.reload.destroyed?).to be_false
179
+ expect(@model2.reload.destroyed?).to be_false
180
+ end
181
+ end
182
+
183
+ context 'when restore(instance method)' do
184
+ before :each do
185
+ @model.destroy
186
+ end
187
+
188
+ it 'restore model' do
189
+ expect{
190
+ @model.restore!
191
+ }.to change(ParanoidModel, :count).by(1)
192
+
193
+ expect(@model.reload.destroyed?).to be_false
194
+ end
195
+
196
+ it 'call callbacks of restore.' do
197
+ ParanoidModel.before_restore :before_restore_callback
198
+ ParanoidModel.after_restore :after_restore_callback
199
+ ParanoidModel.after_commit :after_commit_callback
200
+
201
+ @model.should_receive(:before_restore_callback).once
202
+ @model.should_receive(:after_restore_callback).once
203
+ @model.should_receive(:after_commit_callback).once.and_return(true)
204
+
205
+ @model.restore!
206
+ end
207
+
208
+ it 'not call callbacks without restore.' do
209
+ ParanoidModel.before_update :before_update_callback
210
+ ParanoidModel.before_save :before_save_callback
211
+ ParanoidModel.validate :validate_callback
212
+
213
+ @model.should_receive(:before_update_callback).exactly(0).times
214
+ @model.should_receive(:before_save_callback).exactly(0).times
215
+ @model.should_receive(:validate_callback).exactly(0).times
216
+
217
+ @model.restore!
218
+ end
219
+
220
+ it 'alias recover to restore!' do
221
+ expect{
222
+ @model.restore!
223
+ }.to change(ParanoidModel, :count).by(1)
224
+
225
+ expect(@model.reload.destroyed?).to be_false
226
+ end
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kakurenbo::SoftDeleteCore::Scopes do
4
+ create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
5
+
6
+ before :each do
7
+ class ParanoidModel < ActiveRecord::Base; end
8
+ end
9
+
10
+ after :each do
11
+ Object.class_eval{ remove_const :ParanoidModel }
12
+ end
13
+
14
+ context 'when call scope of' do
15
+ before :each do
16
+ @existing_model = ParanoidModel.create!
17
+ @deleted_model = ParanoidModel.create!(deleted_at: Time.now)
18
+ end
19
+
20
+ context 'default_scope' do
21
+ it 'show existing model.' do
22
+ expect(ParanoidModel.find_by(id: @existing_model.id)).not_to be_nil
23
+ end
24
+
25
+ it 'hide deleted model.' do
26
+ expect(ParanoidModel.find_by(id: @deleted_model.id)).to be_nil
27
+ end
28
+ end
29
+
30
+ context 'only_deleted' do
31
+ it 'hide existing model.' do
32
+ expect(ParanoidModel.only_deleted.find_by(id: @existing_model.id)).to be_nil
33
+ end
34
+
35
+ it 'show deleted model.' do
36
+ expect(ParanoidModel.only_deleted.find_by(@deleted_model.id)).not_to be_nil
37
+ end
38
+ end
39
+
40
+ context 'with_deleted' do
41
+ it 'show existing model.' do
42
+ expect(ParanoidModel.with_deleted.find_by(id: @existing_model.id)).not_to be_nil
43
+ end
44
+
45
+ it 'show deleted model.' do
46
+ expect(ParanoidModel.with_deleted.find_by(@deleted_model.id)).not_to be_nil
47
+ end
48
+ end
49
+
50
+ context 'without_deleted' do
51
+ it 'show existing model.' do
52
+ expect(ParanoidModel.without_deleted.find_by(id: @existing_model.id)).not_to be_nil
53
+ end
54
+
55
+ it 'hide deleted model.' do
56
+ expect(ParanoidModel.without_deleted.find_by(id: @deleted_model.id)).to be_nil
57
+ end
58
+ end
59
+ end
60
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kakurenbo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - alfa-jpn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-27 00:00:00.000000000 Z
11
+ date: 2014-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -119,7 +119,10 @@ files:
119
119
  - lib/kakurenbo/soft_delete_core.rb
120
120
  - lib/kakurenbo/version.rb
121
121
  - spec/kakurenbo/mixin_ar_base_spec.rb
122
- - spec/kakurenbo/soft_delete_core_spec.rb
122
+ - spec/kakurenbo/soft_delete_cores/associations_spec.rb
123
+ - spec/kakurenbo/soft_delete_cores/callbacks_spec.rb
124
+ - spec/kakurenbo/soft_delete_cores/core_spec.rb
125
+ - spec/kakurenbo/soft_delete_cores/scopes_spec.rb
123
126
  - spec/spec_helper.rb
124
127
  homepage: https://github.com/alfa-jpn/kakurenbo
125
128
  licenses:
@@ -148,6 +151,9 @@ summary: provides soft delete. Kakurenbo is a re-implementation of paranoia and
148
151
  for Rails4 and 3. implemented a function that other gems are not enough.
149
152
  test_files:
150
153
  - spec/kakurenbo/mixin_ar_base_spec.rb
151
- - spec/kakurenbo/soft_delete_core_spec.rb
154
+ - spec/kakurenbo/soft_delete_cores/associations_spec.rb
155
+ - spec/kakurenbo/soft_delete_cores/callbacks_spec.rb
156
+ - spec/kakurenbo/soft_delete_cores/core_spec.rb
157
+ - spec/kakurenbo/soft_delete_cores/scopes_spec.rb
152
158
  - spec/spec_helper.rb
153
159
  has_rdoc:
@@ -1,420 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Kakurenbo::MixinARBase do
4
- create_temp_table(:paranoid_models){ |t| t.datetime :deleted_at }
5
-
6
- create_temp_table(:parent_models) { |t| t.integer :child_id; t.datetime :deleted_at }
7
- create_temp_table(:normal_child_models) { |t| t.integer :parent_model_id }
8
- create_temp_table(:paranoid_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
9
- create_temp_table(:paranoid_single_child_models) { |t| t.integer :parent_model_id; t.datetime :deleted_at }
10
-
11
- context 'when define ParanoidModel' do
12
- before :each do
13
- class ParanoidModel < ActiveRecord::Base; end
14
- end
15
-
16
- after :each do
17
- Object.class_eval{ remove_const :ParanoidModel }
18
- end
19
-
20
- describe 'Callbacks' do
21
- before :each do
22
- @callback_model = ParanoidModel.create!
23
- end
24
-
25
- it 'before_restore.' do
26
- ParanoidModel.before_restore :before_restore_callback
27
- @callback_model.should_receive(:before_restore_callback).once
28
- @callback_model.run_callbacks(:restore)
29
- end
30
-
31
- it 'around_restore.' do
32
- ParanoidModel.around_restore :around_restore_callback
33
- @callback_model.should_receive(:around_restore_callback).once
34
- @callback_model.run_callbacks(:restore)
35
- end
36
-
37
- it 'after_restore.' do
38
- ParanoidModel.after_restore :after_restore_callback
39
- @callback_model.should_receive(:after_restore_callback).once
40
- @callback_model.run_callbacks(:restore)
41
- end
42
- end
43
-
44
-
45
- describe 'Scopes' do
46
- before :each do
47
- @normal_model = ParanoidModel.create!
48
- @deleted_model = ParanoidModel.create!(deleted_at: Time.now)
49
- end
50
-
51
- context 'when use default_scope' do
52
- it 'show normal model.' do
53
- expect(ParanoidModel.find_by(id: @normal_model.id)).not_to be_nil
54
- end
55
-
56
- it 'hide deleted model.' do
57
- expect(ParanoidModel.find_by(id: @deleted_model.id)).to be_nil
58
- end
59
- end
60
-
61
- context 'when use only_deleted' do
62
- it 'show normal model.' do
63
- expect(ParanoidModel.only_deleted.find_by(id: @normal_model.id)).to be_nil
64
- end
65
-
66
- it 'show deleted model.' do
67
- expect(ParanoidModel.only_deleted.find_by(@deleted_model.id)).not_to be_nil
68
- end
69
- end
70
-
71
- context 'when use with_deleted' do
72
- it 'show normal model.' do
73
- expect(ParanoidModel.with_deleted.find_by(id: @normal_model.id)).not_to be_nil
74
- end
75
-
76
- it 'show deleted model.' do
77
- expect(ParanoidModel.with_deleted.find_by(@deleted_model.id)).not_to be_nil
78
- end
79
- end
80
-
81
- context 'when use without_deleted' do
82
- it 'show normal model.' do
83
- expect(ParanoidModel.without_deleted.find_by(id: @normal_model.id)).not_to be_nil
84
- end
85
-
86
- it 'hide deleted model.' do
87
- expect(ParanoidModel.without_deleted.find_by(id: @deleted_model.id)).to be_nil
88
- end
89
- end
90
- end
91
-
92
-
93
- describe 'Core' do
94
- before :each do
95
- @model = ParanoidModel.create!
96
- end
97
-
98
- context 'when delete' do
99
- it 'soft-delete model.' do
100
- expect{
101
- @model.delete
102
- }.to change(ParanoidModel, :count).by(-1)
103
- end
104
-
105
- it 'not hard-delete model.' do
106
- expect{
107
- @model.delete
108
- }.to change{
109
- ParanoidModel.all.with_deleted.count
110
- }.by(0)
111
- end
112
-
113
- it 'call callbacks nothing.' do
114
- ParanoidModel.before_destroy :before_destroy_callback
115
- ParanoidModel.after_destroy :after_destroy_callback
116
- ParanoidModel.after_commit :after_commit_callback
117
-
118
- @model.should_receive(:before_destroy_callback).exactly(0).times
119
- @model.should_receive(:after_destroy_callback).exactly(0).times
120
- @model.should_receive(:after_commit_callback).exactly(0).times
121
-
122
- @model.delete
123
- end
124
-
125
- it 'not call callbacks other.' do
126
- ParanoidModel.before_update :before_update_callback
127
- ParanoidModel.before_save :before_save_callback
128
- ParanoidModel.validate :validate_callback
129
-
130
- @model.should_receive(:before_update_callback).exactly(0).times
131
- @model.should_receive(:before_save_callback).exactly(0).times
132
- @model.should_receive(:validate_callback).exactly(0).times
133
-
134
- @model.delete
135
- end
136
- end
137
-
138
- context 'when delete!' do
139
- it 'hard-delete model.' do
140
- expect{
141
- @model.delete!
142
- }.to change{
143
- ParanoidModel.all.with_deleted.count
144
- }.by(-1)
145
- end
146
- end
147
-
148
- context 'when destroy' do
149
- it 'soft-delete model.' do
150
- expect{
151
- @model.destroy
152
- }.to change(ParanoidModel, :count).by(-1)
153
- end
154
-
155
- it 'not hard-delete model.' do
156
- expect{
157
- @model.destroy
158
- }.to change{
159
- ParanoidModel.all.with_deleted.count
160
- }.by(0)
161
- end
162
-
163
- it 'call callbacks of destroy.' do
164
- ParanoidModel.before_destroy :before_destroy_callback
165
- ParanoidModel.after_destroy :after_destroy_callback
166
- ParanoidModel.after_commit :after_commit_callback
167
-
168
- @model.should_receive(:before_destroy_callback).once
169
- @model.should_receive(:after_destroy_callback).once
170
- @model.should_receive(:after_commit_callback).once.and_return(true)
171
-
172
- @model.destroy
173
- end
174
-
175
- it 'not call callbacks without destroy.' do
176
- ParanoidModel.before_update :before_update_callback
177
- ParanoidModel.before_save :before_save_callback
178
- ParanoidModel.validate :validate_callback
179
-
180
- @model.should_receive(:before_update_callback).exactly(0).times
181
- @model.should_receive(:before_save_callback).exactly(0).times
182
- @model.should_receive(:validate_callback).exactly(0).times
183
-
184
- @model.destroy
185
- end
186
- end
187
-
188
- context 'when destroy!' do
189
- it 'hard-delete model.' do
190
- expect{
191
- @model.destroy!
192
- }.to change{
193
- ParanoidModel.all.with_deleted.count
194
- }.by(-1)
195
- end
196
- end
197
-
198
- context 'when destroyed?' do
199
- it 'false if model not destroyed.' do
200
- expect(@model.destroyed?).to be_false
201
- end
202
-
203
- it 'false if model destroyed.' do
204
- @model.destroy
205
- expect(@model.destroyed?).to be_true
206
- end
207
-
208
- it 'alias_method deleted? to destroyed?' do
209
- expect(@model.deleted?).to be_false
210
- end
211
- end
212
-
213
- context 'when restore.(class method)' do
214
- before :each do
215
- @model.destroy
216
- end
217
-
218
- it 'with id restore of instance method.' do
219
- expect{
220
- ParanoidModel.restore(@model.id)
221
- }.to change(ParanoidModel, :count).by(1)
222
-
223
- expect(@model.reload.destroyed?).to be_false
224
- end
225
-
226
- it 'with ids restore of instance method.' do
227
- @model2 = ParanoidModel.create!
228
- @model2.destroy
229
-
230
- expect{
231
- ParanoidModel.restore([@model.id, @model2.id])
232
- }.to change(ParanoidModel, :count).by(2)
233
-
234
- expect(@model.reload.destroyed?).to be_false
235
- expect(@model2.reload.destroyed?).to be_false
236
- end
237
- end
238
-
239
- context 'when restore.(instance method)' do
240
- before :each do
241
- @model.destroy
242
- end
243
-
244
- it 'restore model' do
245
- expect{
246
- @model.restore!
247
- }.to change(ParanoidModel, :count).by(1)
248
-
249
- expect(@model.reload.destroyed?).to be_false
250
- end
251
-
252
- it 'call callbacks of restore.' do
253
- ParanoidModel.before_restore :before_restore_callback
254
- ParanoidModel.after_restore :after_restore_callback
255
- ParanoidModel.after_commit :after_commit_callback
256
-
257
- @model.should_receive(:before_restore_callback).once
258
- @model.should_receive(:after_restore_callback).once
259
- @model.should_receive(:after_commit_callback).once.and_return(true)
260
-
261
- @model.restore!
262
- end
263
-
264
- it 'not call callbacks without restore.' do
265
- ParanoidModel.before_update :before_update_callback
266
- ParanoidModel.before_save :before_save_callback
267
- ParanoidModel.validate :validate_callback
268
-
269
- @model.should_receive(:before_update_callback).exactly(0).times
270
- @model.should_receive(:before_save_callback).exactly(0).times
271
- @model.should_receive(:validate_callback).exactly(0).times
272
-
273
- @model.restore!
274
- end
275
- end
276
- end
277
- end
278
-
279
-
280
- context 'when define relation model' do
281
- before :all do
282
- class NormalChildModel < ActiveRecord::Base; end
283
- class ParanoidChildModel < ActiveRecord::Base; end
284
- class ParanoidSingleChildModel < ActiveRecord::Base; end
285
- class ParentModel < ActiveRecord::Base
286
- has_many :normal_child_models, :dependent => :destroy
287
- has_many :paranoid_child_models, :dependent => :destroy
288
-
289
- has_one :paranoid_single_child_model, :dependent => :destroy
290
- belongs_to :child, :class_name => :ParanoidSingleChildModel, :dependent => :destroy
291
- end
292
- end
293
-
294
- describe 'NormalChildModel' do
295
- before :each do
296
- @parent = ParentModel.create!
297
- @first = @parent.normal_child_models.create!
298
- @second = @parent.normal_child_models.create!
299
- end
300
-
301
- context 'when parent was destroyed' do
302
- it 'remove normal_child_models' do
303
- expect{@parent.destroy}.to change(NormalChildModel, :count).by(-2)
304
- expect(@first.destroyed?).to be_true
305
- expect(@second.destroyed?).to be_true
306
- end
307
- end
308
- end
309
-
310
- describe 'ParanoidChildModel' do
311
- before :each do
312
- @parent = ParentModel.create!
313
- @first = @parent.paranoid_child_models.create!
314
- @second = @parent.paranoid_child_models.create!
315
- @third = @parent.paranoid_child_models.create!
316
- end
317
-
318
- context 'when parent was destroyed' do
319
- it 'remove normal_child_models' do
320
- expect{@parent.destroy}.to change(ParanoidChildModel, :count).by(-3)
321
- expect(@first.reload.destroyed?).to be_true
322
- expect(@second.reload.destroyed?).to be_true
323
- expect(@third.reload.destroyed?).to be_true
324
- end
325
-
326
- it 'restore with normal_child_models' do
327
- @parent.destroy
328
- expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(3)
329
- expect(@first.reload.destroyed?).to be_false
330
- expect(@second.reload.destroyed?).to be_false
331
- expect(@third.reload.destroyed?).to be_false
332
- end
333
-
334
- it 'not restore model that was deleted before parent was deleted.' do
335
- # Delete before parent was deleted.
336
- delete_at = 1.second.ago
337
- Time.stub(:now).and_return(delete_at)
338
- @first.destroy
339
-
340
- # Delete after first_child was deleted.
341
- Time.unstub(:now)
342
- @parent.destroy
343
-
344
- expect{@parent.restore!}.to change(ParanoidChildModel, :count).by(2)
345
- expect(@first.reload.destroyed?).to be_true
346
- expect(@second.reload.destroyed?).to be_false
347
- expect(@third.reload.destroyed?).to be_false
348
- end
349
- end
350
- end
351
-
352
- describe 'ParanoidSingleChildModel' do
353
- before :each do
354
- @parent = ParentModel.create!
355
- @first = ParanoidSingleChildModel.create!(parent_model_id: @parent.id)
356
- end
357
-
358
- context 'when parent was destroyed' do
359
- it 'remove normal_child_models' do
360
- expect{@parent.destroy}.to change(ParanoidSingleChildModel, :count).by(-1)
361
- expect(@first.reload.destroyed?).to be_true
362
- end
363
-
364
- it 'restore with normal_child_models' do
365
- @parent.destroy
366
- expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(1)
367
- expect(@first.reload.destroyed?).to be_false
368
- end
369
-
370
- it 'not restore model that was deleted before parent was deleted.' do
371
- # Delete before parent was deleted.
372
- delete_at = 1.second.ago
373
- Time.stub(:now).and_return(delete_at)
374
- @first.destroy
375
-
376
- # Delete after first_child was deleted.
377
- Time.unstub(:now)
378
- @parent.destroy
379
-
380
- expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(0)
381
- expect(@first.reload.destroyed?).to be_true
382
- end
383
- end
384
- end
385
-
386
- describe 'ParanoidSingleChildModel' do
387
- before :each do
388
- @first = ParanoidSingleChildModel.create!
389
- @parent = ParentModel.create!(child_id: @first.id)
390
- end
391
-
392
- context 'when parent was destroyed' do
393
- it 'remove normal_child_models' do
394
- expect{@parent.destroy}.to change(ParanoidSingleChildModel, :count).by(-1)
395
- expect(@first.reload.destroyed?).to be_true
396
- end
397
-
398
- it 'restore with normal_child_models' do
399
- @parent.destroy
400
- expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(1)
401
- expect(@first.reload.destroyed?).to be_false
402
- end
403
-
404
- it 'not restore model that was deleted before parent was deleted.' do
405
- # Delete before parent was deleted.
406
- delete_at = 1.second.ago
407
- Time.stub(:now).and_return(delete_at)
408
- @first.destroy
409
-
410
- # Delete after first_child was deleted.
411
- Time.unstub(:now)
412
- @parent.destroy
413
-
414
- expect{@parent.restore!}.to change(ParanoidSingleChildModel, :count).by(0)
415
- expect(@first.reload.destroyed?).to be_true
416
- end
417
- end
418
- end
419
- end
420
- end