massive_record 0.2.2.rc1 → 0.2.2.rc2
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/CHANGELOG.md +4 -1
- data/lib/massive_record/orm/embedded.rb +2 -0
- data/lib/massive_record/orm/in_the_middle_of_saving_tracker.rb +75 -0
- data/lib/massive_record/orm/persistence/operations.rb +9 -2
- data/lib/massive_record/orm/relations/proxy/embeds_many.rb +1 -1
- data/lib/massive_record/version.rb +1 -1
- data/spec/orm/cases/callbacks_spec.rb +128 -284
- data/spec/orm/models/callback_testable.rb +44 -0
- data/spec/orm/persistence/operations_spec.rb +18 -0
- data/spec/shared/orm/callbacks.rb +316 -0
- metadata +7 -2
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# v0.2.2 (git develop)
|
2
2
|
|
3
3
|
|
4
|
-
# v0.2.2.
|
4
|
+
# v0.2.2.rc2 (git master)
|
5
|
+
- Fixed some issues related to callbacks on embedded records.
|
6
|
+
|
7
|
+
# v0.2.2.rc1
|
5
8
|
|
6
9
|
- ProxyCollection destroy_all and delete_all returns removed records.
|
7
10
|
- Changes are better detected on new records. user = User.new :email => "me@gmail.com"; user.email_changed?
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'massive_record/orm/schema/embedded_interface'
|
2
|
+
require 'massive_record/orm/in_the_middle_of_saving_tracker'
|
2
3
|
|
3
4
|
module MassiveRecord
|
4
5
|
module ORM
|
5
6
|
class Embedded < Base
|
6
7
|
include Schema::EmbeddedInterface
|
8
|
+
include InTheMiddleOfSavingTracker
|
7
9
|
|
8
10
|
DATABASE_ID_SEPARATOR = '|'
|
9
11
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module MassiveRecord
|
2
|
+
module ORM
|
3
|
+
|
4
|
+
#
|
5
|
+
# Tracks if we are in the middle of being saved or not, and if
|
6
|
+
# we are asked valid? in the middle of a save, we'll return the
|
7
|
+
# last answer we gave to that question, instead of running
|
8
|
+
# validations again.
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Main reason for doing so is when used in conjunction with
|
12
|
+
# Embedded records, in the following situations:
|
13
|
+
#
|
14
|
+
# 1. Calling save on an embedded record when the owner
|
15
|
+
# is not persisted will call save on the same
|
16
|
+
# record again when owner is saved and informs
|
17
|
+
# embeds many proxy that it is being about to be
|
18
|
+
# saved. Resulting in all callbacks fire again
|
19
|
+
# on the record which issued the save in the first
|
20
|
+
# place.
|
21
|
+
#
|
22
|
+
# We can query each embedded record inside of
|
23
|
+
# embeds_many#parent_will_be_saved! if we are to call save
|
24
|
+
# on it (to make each embedded record update it's persisted state),
|
25
|
+
# or if we should not do it, if the embedded record was the one
|
26
|
+
# triggered the save in the first place.
|
27
|
+
#
|
28
|
+
# 2. Calling save on an embedded record when the owner
|
29
|
+
# is not persisted will first validate the embedded
|
30
|
+
# record, then the owner will validate all associated
|
31
|
+
# records, including the one record which issued
|
32
|
+
# the save and therefor is validated.
|
33
|
+
#
|
34
|
+
# We can controll if we are to run validations on a record
|
35
|
+
# or not, based if we are in the middle of a save on current
|
36
|
+
# record, thus callbacks (like before_validations etc) will
|
37
|
+
# not run twice.
|
38
|
+
#
|
39
|
+
module InTheMiddleOfSavingTracker
|
40
|
+
attr_reader :in_the_middle_of_saving
|
41
|
+
alias in_the_middle_of_saving? in_the_middle_of_saving
|
42
|
+
|
43
|
+
def save(options = {})
|
44
|
+
with_in_the_middle_of_saving_tracker { super }
|
45
|
+
end
|
46
|
+
|
47
|
+
def save!(options = {})
|
48
|
+
with_in_the_middle_of_saving_tracker { super }
|
49
|
+
end
|
50
|
+
|
51
|
+
def valid?(*)
|
52
|
+
if in_the_middle_of_saving?
|
53
|
+
if @last_valid_value_inside_of_current_save.nil?
|
54
|
+
@last_valid_value_inside_of_current_save = super
|
55
|
+
else
|
56
|
+
@last_valid_value_inside_of_current_save
|
57
|
+
end
|
58
|
+
else
|
59
|
+
super
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def with_in_the_middle_of_saving_tracker
|
67
|
+
@in_the_middle_of_saving = true
|
68
|
+
yield
|
69
|
+
ensure
|
70
|
+
@in_the_middle_of_saving = false
|
71
|
+
@last_valid_value_inside_of_current_save = nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -32,10 +32,17 @@ module MassiveRecord
|
|
32
32
|
module Operations
|
33
33
|
class << self
|
34
34
|
def suppress
|
35
|
-
@suppressed = true
|
35
|
+
suppressed_was, @suppressed = @suppressed, true
|
36
36
|
yield
|
37
37
|
ensure
|
38
|
-
@suppressed =
|
38
|
+
@suppressed = suppressed_was
|
39
|
+
end
|
40
|
+
|
41
|
+
def force
|
42
|
+
suppressed_was, @suppressed = @suppressed, false
|
43
|
+
yield
|
44
|
+
ensure
|
45
|
+
@suppressed = suppressed_was
|
39
46
|
end
|
40
47
|
|
41
48
|
def suppressed?
|
@@ -93,7 +93,7 @@ module MassiveRecord
|
|
93
93
|
if record.destroyed?
|
94
94
|
proxy_targets_update_hash[record.database_id] = nil
|
95
95
|
elsif record.new_record? || record.changed?
|
96
|
-
record.save
|
96
|
+
record.save(:validate => false) unless record.in_the_middle_of_saving?
|
97
97
|
proxy_targets_update_hash[record.database_id] = Base.coder.dump(record.attributes_db_raw_data_hash)
|
98
98
|
end
|
99
99
|
end
|
@@ -1,309 +1,153 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'orm/models/callback_testable'
|
2
3
|
require 'orm/models/person'
|
3
4
|
require 'orm/models/address'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
shared_examples_for "Massive Record with callbacks" do
|
9
|
-
it "should include ActiveModel::Callbacks" do
|
10
|
-
@model.class.should respond_to :define_model_callbacks
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should include ActiveModell::Validations::Callback" do
|
14
|
-
@model.class.included_modules.should include(ActiveModel::Validations::Callbacks)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
{
|
19
|
-
"MassiveRecord::Base::Table" => Person,
|
20
|
-
"MassiveRecord::Base::Column" => Address
|
21
|
-
}.each do |orm_class, inherited_by_test_class|
|
22
|
-
describe orm_class do
|
23
|
-
before do
|
24
|
-
@model = inherited_by_test_class.new
|
25
|
-
end
|
26
|
-
|
27
|
-
it_should_behave_like "Massive Record with callbacks"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
#
|
33
|
-
# Some real life object tests
|
34
|
-
#
|
35
|
-
class CallbackDeveloper < MassiveRecord::ORM::Table
|
36
|
-
class << self
|
37
|
-
def callback_string(callback_method)
|
38
|
-
"history << [#{callback_method.to_sym.inspect}, :string]"
|
39
|
-
end
|
6
|
+
describe "callbacks on" do
|
7
|
+
include SetUpHbaseConnectionBeforeAll
|
8
|
+
include SetTableNamesToTestTable
|
40
9
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
10
|
+
class CallbackDeveloperTable < MassiveRecord::ORM::Table
|
11
|
+
include CallbackTestable
|
44
12
|
|
45
|
-
|
46
|
-
define_method(callback_method) do
|
47
|
-
self.history << [callback_method, :method]
|
48
|
-
end
|
49
|
-
send(callback_method, :"#{callback_method}")
|
50
|
-
end
|
13
|
+
embeds_many :callback_developer_embeddeds, :store_in => :base
|
51
14
|
|
52
|
-
|
53
|
-
|
54
|
-
klass.send(:define_method, callback_method) do |model|
|
55
|
-
model.history << [callback_method, :object]
|
56
|
-
end
|
57
|
-
klass.new
|
15
|
+
column_family :base do
|
16
|
+
field :name, :default => "Thorbjorn"
|
58
17
|
end
|
59
18
|
end
|
60
19
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
20
|
+
describe CallbackDeveloperTable do
|
21
|
+
let(:new_record) { described_class.new "1" }
|
22
|
+
let(:created_record) { described_class.create "dummy" }
|
23
|
+
let(:persisted_record) do
|
24
|
+
described_class.create! "1"
|
25
|
+
described_class.find "1"
|
26
|
+
end
|
69
27
|
|
70
|
-
|
71
|
-
@history ||= []
|
28
|
+
it_should_behave_like "a model with callbacks"
|
72
29
|
end
|
73
|
-
end
|
74
30
|
|
75
31
|
|
76
|
-
describe "callbacks for" do
|
77
|
-
include MockMassiveRecordConnection
|
78
32
|
|
79
|
-
it "initialize should run in correct order" do
|
80
|
-
thorbjorn = CallbackDeveloper.new
|
81
|
-
thorbjorn.history.should == [
|
82
|
-
[:after_initialize, :method],
|
83
|
-
[:after_initialize, :string],
|
84
|
-
[:after_initialize, :proc],
|
85
|
-
[:after_initialize, :object],
|
86
|
-
[:after_initialize, :block]
|
87
|
-
]
|
88
|
-
end
|
89
33
|
|
90
|
-
|
91
|
-
|
92
|
-
thorbjorn.history.should == [
|
93
|
-
[:after_find, :method],
|
94
|
-
[:after_find, :string],
|
95
|
-
[:after_find, :proc],
|
96
|
-
[:after_find, :object],
|
97
|
-
[:after_find, :block],
|
98
|
-
[:after_initialize, :method],
|
99
|
-
[:after_initialize, :string],
|
100
|
-
[:after_initialize, :proc],
|
101
|
-
[:after_initialize, :object],
|
102
|
-
[:after_initialize, :block]
|
103
|
-
]
|
104
|
-
end
|
34
|
+
class CallbackDeveloperEmbedded < MassiveRecord::ORM::Embedded
|
35
|
+
include CallbackTestable
|
105
36
|
|
106
|
-
|
107
|
-
thorbjorn = CallbackDeveloper.find(1)
|
108
|
-
thorbjorn.touch
|
109
|
-
thorbjorn.history.should == [
|
110
|
-
[:after_find, :method],
|
111
|
-
[:after_find, :string],
|
112
|
-
[:after_find, :proc],
|
113
|
-
[:after_find, :object],
|
114
|
-
[:after_find, :block],
|
115
|
-
[:after_initialize, :method],
|
116
|
-
[:after_initialize, :string],
|
117
|
-
[:after_initialize, :proc],
|
118
|
-
[:after_initialize, :object],
|
119
|
-
[:after_initialize, :block],
|
120
|
-
[:after_touch, :method],
|
121
|
-
[:after_touch, :string],
|
122
|
-
[:after_touch, :proc],
|
123
|
-
[:after_touch, :object],
|
124
|
-
[:after_touch, :block]
|
125
|
-
]
|
126
|
-
end
|
127
|
-
|
128
|
-
it "valid for new record should run in correct order" do
|
129
|
-
thorbjorn = CallbackDeveloper.new
|
130
|
-
thorbjorn.valid?
|
131
|
-
thorbjorn.history.should == [
|
132
|
-
[:after_initialize, :method],
|
133
|
-
[:after_initialize, :string],
|
134
|
-
[:after_initialize, :proc],
|
135
|
-
[:after_initialize, :object],
|
136
|
-
[:after_initialize, :block],
|
137
|
-
[:before_validation, :method],
|
138
|
-
[:before_validation, :string],
|
139
|
-
[:before_validation, :proc],
|
140
|
-
[:before_validation, :object],
|
141
|
-
[:before_validation, :block],
|
142
|
-
[:after_validation, :method],
|
143
|
-
[:after_validation, :string],
|
144
|
-
[:after_validation, :proc],
|
145
|
-
[:after_validation, :object],
|
146
|
-
[:after_validation, :block]
|
147
|
-
]
|
148
|
-
end
|
37
|
+
embedded_in :callback_developer_table
|
149
38
|
|
150
|
-
|
151
|
-
thorbjorn = CallbackDeveloper.find(1)
|
152
|
-
thorbjorn.valid?
|
153
|
-
thorbjorn.history.should == [
|
154
|
-
[:after_find, :method],
|
155
|
-
[:after_find, :string],
|
156
|
-
[:after_find, :proc],
|
157
|
-
[:after_find, :object],
|
158
|
-
[:after_find, :block],
|
159
|
-
[:after_initialize, :method],
|
160
|
-
[:after_initialize, :string],
|
161
|
-
[:after_initialize, :proc],
|
162
|
-
[:after_initialize, :object],
|
163
|
-
[:after_initialize, :block],
|
164
|
-
[:before_validation, :method],
|
165
|
-
[:before_validation, :string],
|
166
|
-
[:before_validation, :proc],
|
167
|
-
[:before_validation, :object],
|
168
|
-
[:before_validation, :block],
|
169
|
-
[:after_validation, :method],
|
170
|
-
[:after_validation, :string],
|
171
|
-
[:after_validation, :proc],
|
172
|
-
[:after_validation, :object],
|
173
|
-
[:after_validation, :block]
|
174
|
-
]
|
39
|
+
field :name, :default => "Trym"
|
175
40
|
end
|
176
41
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
[:after_initialize, :method],
|
181
|
-
[:after_initialize, :string],
|
182
|
-
[:after_initialize, :proc ],
|
183
|
-
[:after_initialize, :object],
|
184
|
-
[:after_initialize, :block ],
|
185
|
-
[:before_validation, :method],
|
186
|
-
[:before_validation, :string],
|
187
|
-
[:before_validation, :proc ],
|
188
|
-
[:before_validation, :object],
|
189
|
-
[:before_validation, :block ],
|
190
|
-
[:after_validation, :method],
|
191
|
-
[:after_validation, :string],
|
192
|
-
[:after_validation, :proc ],
|
193
|
-
[:after_validation, :object],
|
194
|
-
[:after_validation, :block ],
|
195
|
-
[:before_save, :method],
|
196
|
-
[:before_save, :string],
|
197
|
-
[:before_save, :proc ],
|
198
|
-
[:before_save, :object],
|
199
|
-
[:before_save, :block ],
|
200
|
-
[:before_create, :method],
|
201
|
-
[:before_create, :string],
|
202
|
-
[:before_create, :proc ],
|
203
|
-
[:before_create, :object],
|
204
|
-
[:before_create, :block ],
|
205
|
-
[:after_create, :method],
|
206
|
-
[:after_create, :string],
|
207
|
-
[:after_create, :proc ],
|
208
|
-
[:after_create, :object],
|
209
|
-
[:after_create, :block ],
|
210
|
-
[:after_save, :method],
|
211
|
-
[:after_save, :string],
|
212
|
-
[:after_save, :proc ],
|
213
|
-
[:after_save, :object],
|
214
|
-
[:after_save, :block ]
|
215
|
-
]
|
216
|
-
end
|
42
|
+
describe CallbackDeveloperEmbedded do
|
43
|
+
let(:owner_new_record) { CallbackDeveloperTable.new "1" }
|
44
|
+
let(:owner) { owner_new_record.save! ; owner_new_record }
|
217
45
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
[:after_find, :object],
|
226
|
-
[:after_find, :block],
|
227
|
-
[:after_initialize, :method],
|
228
|
-
[:after_initialize, :string],
|
229
|
-
[:after_initialize, :proc ],
|
230
|
-
[:after_initialize, :object],
|
231
|
-
[:after_initialize, :block ],
|
232
|
-
[:before_validation, :method],
|
233
|
-
[:before_validation, :string],
|
234
|
-
[:before_validation, :proc ],
|
235
|
-
[:before_validation, :object],
|
236
|
-
[:before_validation, :block ],
|
237
|
-
[:after_validation, :method],
|
238
|
-
[:after_validation, :string],
|
239
|
-
[:after_validation, :proc ],
|
240
|
-
[:after_validation, :object],
|
241
|
-
[:after_validation, :block ],
|
242
|
-
[:before_save, :method],
|
243
|
-
[:before_save, :string],
|
244
|
-
[:before_save, :proc ],
|
245
|
-
[:before_save, :object],
|
246
|
-
[:before_save, :block ],
|
247
|
-
[:before_update, :method],
|
248
|
-
[:before_update, :string],
|
249
|
-
[:before_update, :proc ],
|
250
|
-
[:before_update, :object],
|
251
|
-
[:before_update, :block ],
|
252
|
-
[:after_update, :method],
|
253
|
-
[:after_update, :string],
|
254
|
-
[:after_update, :proc ],
|
255
|
-
[:after_update, :object],
|
256
|
-
[:after_update, :block ],
|
257
|
-
[:after_save, :method],
|
258
|
-
[:after_save, :string],
|
259
|
-
[:after_save, :proc ],
|
260
|
-
[:after_save, :object],
|
261
|
-
[:after_save, :block ]
|
262
|
-
]
|
263
|
-
end
|
46
|
+
let(:new_record) { described_class.new "1", :callback_developer_table => owner_new_record }
|
47
|
+
let(:created_record) { described_class.create "dummy", :callback_developer_table => owner_new_record }
|
48
|
+
let(:persisted_record) do
|
49
|
+
owner.callback_developer_embeddeds << described_class.new("1-1")
|
50
|
+
owner.callback_developer_embeddeds.reset # Resets to drop all proxy cached records, force reload from DB
|
51
|
+
owner.callback_developer_embeddeds.find("1-1")
|
52
|
+
end
|
264
53
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
54
|
+
it_should_behave_like "a model with callbacks"
|
55
|
+
|
56
|
+
|
57
|
+
describe "saved via owner" do
|
58
|
+
context "when owner is new record" do
|
59
|
+
subject { new_record }
|
60
|
+
before { subject } # Tap to initialize
|
61
|
+
|
62
|
+
describe "save callbacks" do
|
63
|
+
it "runs in correct order" do
|
64
|
+
owner_new_record.save
|
65
|
+
subject.history.should eq [
|
66
|
+
[:after_initialize, :method],
|
67
|
+
[:after_initialize, :string],
|
68
|
+
[:after_initialize, :proc ],
|
69
|
+
[:after_initialize, :object],
|
70
|
+
[:after_initialize, :block ],
|
71
|
+
[:before_validation, :method],
|
72
|
+
[:before_validation, :string],
|
73
|
+
[:before_validation, :proc ],
|
74
|
+
[:before_validation, :object],
|
75
|
+
[:before_validation, :block ],
|
76
|
+
[:after_validation, :method],
|
77
|
+
[:after_validation, :string],
|
78
|
+
[:after_validation, :proc ],
|
79
|
+
[:after_validation, :object],
|
80
|
+
[:after_validation, :block ],
|
81
|
+
[:before_save, :method],
|
82
|
+
[:before_save, :string],
|
83
|
+
[:before_save, :proc ],
|
84
|
+
[:before_save, :object],
|
85
|
+
[:before_save, :block ],
|
86
|
+
[:before_create, :method],
|
87
|
+
[:before_create, :string],
|
88
|
+
[:before_create, :proc ],
|
89
|
+
[:before_create, :object],
|
90
|
+
[:before_create, :block ],
|
91
|
+
[:after_create, :method],
|
92
|
+
[:after_create, :string],
|
93
|
+
[:after_create, :proc ],
|
94
|
+
[:after_create, :object],
|
95
|
+
[:after_create, :block ],
|
96
|
+
[:after_save, :method],
|
97
|
+
[:after_save, :string],
|
98
|
+
[:after_save, :proc ],
|
99
|
+
[:after_save, :object],
|
100
|
+
[:after_save, :block ]
|
101
|
+
]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
291
105
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
106
|
+
context "when owner is persisted" do
|
107
|
+
subject { persisted_record; owner.callback_developer_embeddeds.first }
|
108
|
+
before { subject } # Tap to initialize
|
109
|
+
|
110
|
+
describe "update callbacks" do
|
111
|
+
it "is run in correct order" do
|
112
|
+
subject.name += "_NEW"
|
113
|
+
subject.history.clear
|
114
|
+
owner.save
|
115
|
+
subject.history.should eq [
|
116
|
+
[:before_validation, :method],
|
117
|
+
[:before_validation, :string],
|
118
|
+
[:before_validation, :proc ],
|
119
|
+
[:before_validation, :object],
|
120
|
+
[:before_validation, :block ],
|
121
|
+
[:after_validation, :method],
|
122
|
+
[:after_validation, :string],
|
123
|
+
[:after_validation, :proc ],
|
124
|
+
[:after_validation, :object],
|
125
|
+
[:after_validation, :block ],
|
126
|
+
[:before_save, :method],
|
127
|
+
[:before_save, :string],
|
128
|
+
[:before_save, :proc ],
|
129
|
+
[:before_save, :object],
|
130
|
+
[:before_save, :block ],
|
131
|
+
[:before_update, :method],
|
132
|
+
[:before_update, :string],
|
133
|
+
[:before_update, :proc ],
|
134
|
+
[:before_update, :object],
|
135
|
+
[:before_update, :block ],
|
136
|
+
[:after_update, :method],
|
137
|
+
[:after_update, :string],
|
138
|
+
[:after_update, :proc ],
|
139
|
+
[:after_update, :object],
|
140
|
+
[:after_update, :block ],
|
141
|
+
[:after_save, :method],
|
142
|
+
[:after_save, :string],
|
143
|
+
[:after_save, :proc ],
|
144
|
+
[:after_save, :object],
|
145
|
+
[:after_save, :block ]
|
146
|
+
]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
308
151
|
end
|
309
152
|
end
|
153
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CallbackTestable
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
MassiveRecord::ORM::Callbacks::CALLBACKS.each do |callback_method|
|
6
|
+
next if callback_method.to_s =~ /^around_/
|
7
|
+
define_callback_method(callback_method)
|
8
|
+
send(callback_method, callback_string(callback_method))
|
9
|
+
send(callback_method, callback_proc(callback_method))
|
10
|
+
send(callback_method, callback_object(callback_method))
|
11
|
+
send(callback_method) { |model| model.history << [callback_method, :block] }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def callback_string(callback_method)
|
17
|
+
"history << [#{callback_method.to_sym.inspect}, :string]"
|
18
|
+
end
|
19
|
+
|
20
|
+
def callback_proc(callback_method)
|
21
|
+
Proc.new { |model| model.history << [callback_method, :proc] }
|
22
|
+
end
|
23
|
+
|
24
|
+
def define_callback_method(callback_method)
|
25
|
+
define_method(callback_method) do
|
26
|
+
self.history << [callback_method, :method]
|
27
|
+
end
|
28
|
+
send(callback_method, :"#{callback_method}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def callback_object(callback_method)
|
32
|
+
klass = Class.new
|
33
|
+
klass.send(:define_method, callback_method) do |model|
|
34
|
+
model.history << [callback_method, :object]
|
35
|
+
end
|
36
|
+
klass.new
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def history
|
42
|
+
@history ||= []
|
43
|
+
end
|
44
|
+
end
|
@@ -26,6 +26,15 @@ describe MassiveRecord::ORM::Persistence::Operations do
|
|
26
26
|
subject.should be_instance_of MassiveRecord::ORM::Persistence::Operations::Suppress
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
it "is possible to force" do
|
31
|
+
MassiveRecord::ORM::Persistence::Operations.suppress do
|
32
|
+
MassiveRecord::ORM::Persistence::Operations.force do
|
33
|
+
klass = "MassiveRecord::ORM::Persistence::Operations::#{method.to_s.classify}".constantize
|
34
|
+
should be_instance_of klass
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
29
38
|
end
|
30
39
|
end
|
31
40
|
end
|
@@ -51,6 +60,15 @@ describe MassiveRecord::ORM::Persistence::Operations do
|
|
51
60
|
subject.should be_instance_of MassiveRecord::ORM::Persistence::Operations::Suppress
|
52
61
|
end
|
53
62
|
end
|
63
|
+
|
64
|
+
it "is possible to force" do
|
65
|
+
MassiveRecord::ORM::Persistence::Operations.suppress do
|
66
|
+
MassiveRecord::ORM::Persistence::Operations.force do
|
67
|
+
klass = "MassiveRecord::ORM::Persistence::Operations::Embedded::#{method.to_s.classify}".constantize
|
68
|
+
should be_instance_of klass
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
54
72
|
end
|
55
73
|
end
|
56
74
|
end
|
@@ -0,0 +1,316 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for "a model with callbacks" do
|
4
|
+
it "should include ActiveModel::Callbacks" do
|
5
|
+
described_class.should respond_to :define_model_callbacks
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should include ActiveModell::Validations::Callback" do
|
9
|
+
described_class.included_modules.should include(ActiveModel::Validations::Callbacks)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
context "new record" do
|
15
|
+
describe "initialize callbacks" do
|
16
|
+
it "runs in correct order" do
|
17
|
+
subject.history.should eq [
|
18
|
+
[:after_initialize, :method],
|
19
|
+
[:after_initialize, :string],
|
20
|
+
[:after_initialize, :proc],
|
21
|
+
[:after_initialize, :object],
|
22
|
+
[:after_initialize, :block]
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "validations callback" do
|
28
|
+
it "runs in correct order for new records" do
|
29
|
+
subject.valid?
|
30
|
+
subject.history.should eq [
|
31
|
+
[:after_initialize, :method],
|
32
|
+
[:after_initialize, :string],
|
33
|
+
[:after_initialize, :proc],
|
34
|
+
[:after_initialize, :object],
|
35
|
+
[:after_initialize, :block],
|
36
|
+
[:before_validation, :method],
|
37
|
+
[:before_validation, :string],
|
38
|
+
[:before_validation, :proc],
|
39
|
+
[:before_validation, :object],
|
40
|
+
[:before_validation, :block],
|
41
|
+
[:after_validation, :method],
|
42
|
+
[:after_validation, :string],
|
43
|
+
[:after_validation, :proc],
|
44
|
+
[:after_validation, :object],
|
45
|
+
[:after_validation, :block]
|
46
|
+
]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "create callbacks" do
|
51
|
+
subject { created_record }
|
52
|
+
|
53
|
+
it "runs in correct order" do
|
54
|
+
subject.history.should eq [
|
55
|
+
[:after_initialize, :method],
|
56
|
+
[:after_initialize, :string],
|
57
|
+
[:after_initialize, :proc ],
|
58
|
+
[:after_initialize, :object],
|
59
|
+
[:after_initialize, :block ],
|
60
|
+
[:before_validation, :method],
|
61
|
+
[:before_validation, :string],
|
62
|
+
[:before_validation, :proc ],
|
63
|
+
[:before_validation, :object],
|
64
|
+
[:before_validation, :block ],
|
65
|
+
[:after_validation, :method],
|
66
|
+
[:after_validation, :string],
|
67
|
+
[:after_validation, :proc ],
|
68
|
+
[:after_validation, :object],
|
69
|
+
[:after_validation, :block ],
|
70
|
+
[:before_save, :method],
|
71
|
+
[:before_save, :string],
|
72
|
+
[:before_save, :proc ],
|
73
|
+
[:before_save, :object],
|
74
|
+
[:before_save, :block ],
|
75
|
+
[:before_create, :method],
|
76
|
+
[:before_create, :string],
|
77
|
+
[:before_create, :proc ],
|
78
|
+
[:before_create, :object],
|
79
|
+
[:before_create, :block ],
|
80
|
+
[:after_create, :method],
|
81
|
+
[:after_create, :string],
|
82
|
+
[:after_create, :proc ],
|
83
|
+
[:after_create, :object],
|
84
|
+
[:after_create, :block ],
|
85
|
+
[:after_save, :method],
|
86
|
+
[:after_save, :string],
|
87
|
+
[:after_save, :proc ],
|
88
|
+
[:after_save, :object],
|
89
|
+
[:after_save, :block ]
|
90
|
+
]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "save callbacks" do
|
95
|
+
subject { new_record }
|
96
|
+
|
97
|
+
it "runs in correct order" do
|
98
|
+
subject.save
|
99
|
+
subject.history.should eq [
|
100
|
+
[:after_initialize, :method],
|
101
|
+
[:after_initialize, :string],
|
102
|
+
[:after_initialize, :proc ],
|
103
|
+
[:after_initialize, :object],
|
104
|
+
[:after_initialize, :block ],
|
105
|
+
[:before_validation, :method],
|
106
|
+
[:before_validation, :string],
|
107
|
+
[:before_validation, :proc ],
|
108
|
+
[:before_validation, :object],
|
109
|
+
[:before_validation, :block ],
|
110
|
+
[:after_validation, :method],
|
111
|
+
[:after_validation, :string],
|
112
|
+
[:after_validation, :proc ],
|
113
|
+
[:after_validation, :object],
|
114
|
+
[:after_validation, :block ],
|
115
|
+
[:before_save, :method],
|
116
|
+
[:before_save, :string],
|
117
|
+
[:before_save, :proc ],
|
118
|
+
[:before_save, :object],
|
119
|
+
[:before_save, :block ],
|
120
|
+
[:before_create, :method],
|
121
|
+
[:before_create, :string],
|
122
|
+
[:before_create, :proc ],
|
123
|
+
[:before_create, :object],
|
124
|
+
[:before_create, :block ],
|
125
|
+
[:after_create, :method],
|
126
|
+
[:after_create, :string],
|
127
|
+
[:after_create, :proc ],
|
128
|
+
[:after_create, :object],
|
129
|
+
[:after_create, :block ],
|
130
|
+
[:after_save, :method],
|
131
|
+
[:after_save, :string],
|
132
|
+
[:after_save, :proc ],
|
133
|
+
[:after_save, :object],
|
134
|
+
[:after_save, :block ]
|
135
|
+
]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
context "persisted record" do
|
142
|
+
subject { persisted_record }
|
143
|
+
|
144
|
+
describe "find callbacks" do
|
145
|
+
it "runs in correct order" do
|
146
|
+
subject.history.should eq [
|
147
|
+
[:after_find, :method],
|
148
|
+
[:after_find, :string],
|
149
|
+
[:after_find, :proc],
|
150
|
+
[:after_find, :object],
|
151
|
+
[:after_find, :block],
|
152
|
+
[:after_initialize, :method],
|
153
|
+
[:after_initialize, :string],
|
154
|
+
[:after_initialize, :proc],
|
155
|
+
[:after_initialize, :object],
|
156
|
+
[:after_initialize, :block]
|
157
|
+
]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
describe "touch callbacks" do
|
163
|
+
it "runs in correct order" do
|
164
|
+
subject.touch
|
165
|
+
subject.history.should eq [
|
166
|
+
[:after_find, :method],
|
167
|
+
[:after_find, :string],
|
168
|
+
[:after_find, :proc],
|
169
|
+
[:after_find, :object],
|
170
|
+
[:after_find, :block],
|
171
|
+
[:after_initialize, :method],
|
172
|
+
[:after_initialize, :string],
|
173
|
+
[:after_initialize, :proc],
|
174
|
+
[:after_initialize, :object],
|
175
|
+
[:after_initialize, :block],
|
176
|
+
[:after_touch, :method],
|
177
|
+
[:after_touch, :string],
|
178
|
+
[:after_touch, :proc],
|
179
|
+
[:after_touch, :object],
|
180
|
+
[:after_touch, :block]
|
181
|
+
]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
describe "validations callback" do
|
188
|
+
it "runs in correct order for persisted records" do
|
189
|
+
subject.valid?
|
190
|
+
subject.history.should eq [
|
191
|
+
[:after_find, :method],
|
192
|
+
[:after_find, :string],
|
193
|
+
[:after_find, :proc],
|
194
|
+
[:after_find, :object],
|
195
|
+
[:after_find, :block],
|
196
|
+
[:after_initialize, :method],
|
197
|
+
[:after_initialize, :string],
|
198
|
+
[:after_initialize, :proc],
|
199
|
+
[:after_initialize, :object],
|
200
|
+
[:after_initialize, :block],
|
201
|
+
[:before_validation, :method],
|
202
|
+
[:before_validation, :string],
|
203
|
+
[:before_validation, :proc],
|
204
|
+
[:before_validation, :object],
|
205
|
+
[:before_validation, :block],
|
206
|
+
[:after_validation, :method],
|
207
|
+
[:after_validation, :string],
|
208
|
+
[:after_validation, :proc],
|
209
|
+
[:after_validation, :object],
|
210
|
+
[:after_validation, :block]
|
211
|
+
]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
describe "update callbacks" do
|
219
|
+
it "runs in the correct order" do
|
220
|
+
subject.save
|
221
|
+
subject.history.should eq [
|
222
|
+
[:after_find, :method],
|
223
|
+
[:after_find, :string],
|
224
|
+
[:after_find, :proc],
|
225
|
+
[:after_find, :object],
|
226
|
+
[:after_find, :block],
|
227
|
+
[:after_initialize, :method],
|
228
|
+
[:after_initialize, :string],
|
229
|
+
[:after_initialize, :proc ],
|
230
|
+
[:after_initialize, :object],
|
231
|
+
[:after_initialize, :block ],
|
232
|
+
[:before_validation, :method],
|
233
|
+
[:before_validation, :string],
|
234
|
+
[:before_validation, :proc ],
|
235
|
+
[:before_validation, :object],
|
236
|
+
[:before_validation, :block ],
|
237
|
+
[:after_validation, :method],
|
238
|
+
[:after_validation, :string],
|
239
|
+
[:after_validation, :proc ],
|
240
|
+
[:after_validation, :object],
|
241
|
+
[:after_validation, :block ],
|
242
|
+
[:before_save, :method],
|
243
|
+
[:before_save, :string],
|
244
|
+
[:before_save, :proc ],
|
245
|
+
[:before_save, :object],
|
246
|
+
[:before_save, :block ],
|
247
|
+
[:before_update, :method],
|
248
|
+
[:before_update, :string],
|
249
|
+
[:before_update, :proc ],
|
250
|
+
[:before_update, :object],
|
251
|
+
[:before_update, :block ],
|
252
|
+
[:after_update, :method],
|
253
|
+
[:after_update, :string],
|
254
|
+
[:after_update, :proc ],
|
255
|
+
[:after_update, :object],
|
256
|
+
[:after_update, :block ],
|
257
|
+
[:after_save, :method],
|
258
|
+
[:after_save, :string],
|
259
|
+
[:after_save, :proc ],
|
260
|
+
[:after_save, :object],
|
261
|
+
[:after_save, :block ]
|
262
|
+
]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
describe "destroy callbacks" do
|
268
|
+
it "runs in correct order" do
|
269
|
+
subject.destroy
|
270
|
+
subject.history.should eq [
|
271
|
+
[:after_find, :method],
|
272
|
+
[:after_find, :string],
|
273
|
+
[:after_find, :proc],
|
274
|
+
[:after_find, :object],
|
275
|
+
[:after_find, :block],
|
276
|
+
[:after_initialize, :method],
|
277
|
+
[:after_initialize, :string],
|
278
|
+
[:after_initialize, :proc ],
|
279
|
+
[:after_initialize, :object],
|
280
|
+
[:after_initialize, :block ],
|
281
|
+
[:before_destroy, :method],
|
282
|
+
[:before_destroy, :string],
|
283
|
+
[:before_destroy, :proc ],
|
284
|
+
[:before_destroy, :object],
|
285
|
+
[:before_destroy, :block ],
|
286
|
+
[:after_destroy, :method],
|
287
|
+
[:after_destroy, :string],
|
288
|
+
[:after_destroy, :proc ],
|
289
|
+
[:after_destroy, :object],
|
290
|
+
[:after_destroy, :block ]
|
291
|
+
]
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
describe "delete callbacks" do
|
298
|
+
it "does not run callbacks for destroy" do
|
299
|
+
subject.delete
|
300
|
+
subject.should be_destroyed
|
301
|
+
subject.history.should eq [
|
302
|
+
[:after_find, :method],
|
303
|
+
[:after_find, :string],
|
304
|
+
[:after_find, :proc],
|
305
|
+
[:after_find, :object],
|
306
|
+
[:after_find, :block],
|
307
|
+
[:after_initialize, :method],
|
308
|
+
[:after_initialize, :string],
|
309
|
+
[:after_initialize, :proc ],
|
310
|
+
[:after_initialize, :object],
|
311
|
+
[:after_initialize, :block ]
|
312
|
+
]
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: massive_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 0.2.2.
|
5
|
+
version: 0.2.2.rc2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Companybook
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-10-
|
13
|
+
date: 2011-10-24 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- lib/massive_record/orm/id_factory/atomic_incrementation.rb
|
123
123
|
- lib/massive_record/orm/id_factory/timestamp.rb
|
124
124
|
- lib/massive_record/orm/identity_map.rb
|
125
|
+
- lib/massive_record/orm/in_the_middle_of_saving_tracker.rb
|
125
126
|
- lib/massive_record/orm/log_subscriber.rb
|
126
127
|
- lib/massive_record/orm/observer.rb
|
127
128
|
- lib/massive_record/orm/persistence.rb
|
@@ -217,6 +218,7 @@ files:
|
|
217
218
|
- spec/orm/models/address.rb
|
218
219
|
- spec/orm/models/address_with_timestamp.rb
|
219
220
|
- spec/orm/models/best_friend.rb
|
221
|
+
- spec/orm/models/callback_testable.rb
|
220
222
|
- spec/orm/models/car.rb
|
221
223
|
- spec/orm/models/friend.rb
|
222
224
|
- spec/orm/models/model_without_default_id.rb
|
@@ -251,6 +253,7 @@ files:
|
|
251
253
|
- spec/orm/schema/field_spec.rb
|
252
254
|
- spec/orm/schema/fields_spec.rb
|
253
255
|
- spec/orm/schema/table_interface_spec.rb
|
256
|
+
- spec/shared/orm/callbacks.rb
|
254
257
|
- spec/shared/orm/coders/an_orm_coder.rb
|
255
258
|
- spec/shared/orm/id_factories.rb
|
256
259
|
- spec/shared/orm/model_with_timestamps.rb
|
@@ -335,6 +338,7 @@ test_files:
|
|
335
338
|
- spec/orm/models/address.rb
|
336
339
|
- spec/orm/models/address_with_timestamp.rb
|
337
340
|
- spec/orm/models/best_friend.rb
|
341
|
+
- spec/orm/models/callback_testable.rb
|
338
342
|
- spec/orm/models/car.rb
|
339
343
|
- spec/orm/models/friend.rb
|
340
344
|
- spec/orm/models/model_without_default_id.rb
|
@@ -369,6 +373,7 @@ test_files:
|
|
369
373
|
- spec/orm/schema/field_spec.rb
|
370
374
|
- spec/orm/schema/fields_spec.rb
|
371
375
|
- spec/orm/schema/table_interface_spec.rb
|
376
|
+
- spec/shared/orm/callbacks.rb
|
372
377
|
- spec/shared/orm/coders/an_orm_coder.rb
|
373
378
|
- spec/shared/orm/id_factories.rb
|
374
379
|
- spec/shared/orm/model_with_timestamps.rb
|