1
1
module InterceptableSpec
2
2
class CallbackRegistry
3
- def initialize
3
+ def initialize ( only : [ ] )
4
4
@calls = [ ]
5
+ @only = only
5
6
end
6
7
7
8
def record_call ( cls , cb )
9
+ return unless @only . empty? || @only . any? { |pat | pat == cb }
8
10
@calls << [ cls , cb ]
9
11
end
10
12
@@ -15,6 +17,8 @@ module CallbackTracking
15
17
extend ActiveSupport ::Concern
16
18
17
19
included do
20
+ field :name , type : String
21
+
18
22
%i(
19
23
validation save create update
20
24
) . each do |what |
@@ -34,196 +38,128 @@ module CallbackTracking
34
38
end
35
39
end
36
40
end
37
- end
38
41
39
- class CbHasOneParent
40
- include Mongoid ::Document
41
-
42
- has_one :child , autosave : true , class_name : "CbHasOneChild" , inverse_of : :parent
42
+ attr_accessor :callback_registry
43
43
44
- def initialize ( callback_registry )
44
+ def initialize ( callback_registry , * args , ** kwargs )
45
45
@callback_registry = callback_registry
46
- super ( )
46
+ super ( * args , ** kwargs )
47
47
end
48
+ end
48
49
49
- attr_accessor :callback_registry
50
-
50
+ module RootInsertable
51
51
def insert_as_root
52
52
@callback_registry &.record_call ( self . class , :insert_into_database )
53
53
super
54
54
end
55
+ end
55
56
57
+ class CbHasOneParent
58
+ include Mongoid ::Document
56
59
include CallbackTracking
60
+ include RootInsertable
61
+
62
+ has_one :child , autosave : true , class_name : "CbHasOneChild" , inverse_of : :parent
57
63
end
58
64
59
65
class CbHasOneChild
60
66
include Mongoid ::Document
67
+ include CallbackTracking
61
68
62
69
belongs_to :parent , class_name : "CbHasOneParent" , inverse_of : :child
63
-
64
- def initialize ( callback_registry )
65
- @callback_registry = callback_registry
66
- super ( )
67
- end
68
-
69
- attr_accessor :callback_registry
70
-
71
- include CallbackTracking
72
70
end
73
71
74
72
class CbHasManyParent
75
73
include Mongoid ::Document
74
+ include CallbackTracking
75
+ include RootInsertable
76
76
77
77
has_many :children , autosave : true , class_name : "CbHasManyChild" , inverse_of : :parent
78
-
79
- def initialize ( callback_registry )
80
- @callback_registry = callback_registry
81
- super ( )
82
- end
83
-
84
- attr_accessor :callback_registry
85
-
86
- def insert_as_root
87
- @callback_registry &.record_call ( self . class , :insert_into_database )
88
- super
89
- end
90
-
91
- include CallbackTracking
92
78
end
93
79
94
80
class CbHasManyChild
95
81
include Mongoid ::Document
82
+ include CallbackTracking
96
83
97
84
belongs_to :parent , class_name : "CbHasManyParent" , inverse_of : :children
98
-
99
- def initialize ( callback_registry )
100
- @callback_registry = callback_registry
101
- super ( )
102
- end
103
-
104
- attr_accessor :callback_registry
105
-
106
- include CallbackTracking
107
85
end
108
86
109
87
class CbEmbedsOneParent
110
88
include Mongoid ::Document
89
+ include CallbackTracking
90
+ include RootInsertable
111
91
112
92
field :name
113
93
114
94
embeds_one :child , cascade_callbacks : true , class_name : "CbEmbedsOneChild" , inverse_of : :parent
115
-
116
- def initialize ( callback_registry )
117
- @callback_registry = callback_registry
118
- super ( )
119
- end
120
-
121
- attr_accessor :callback_registry
122
-
123
- def insert_as_root
124
- @callback_registry &.record_call ( self . class , :insert_into_database )
125
- super
126
- end
127
-
128
- include CallbackTracking
129
95
end
130
96
131
97
class CbEmbedsOneChild
132
98
include Mongoid ::Document
99
+ include CallbackTracking
133
100
134
101
field :age
135
102
136
103
embedded_in :parent , class_name : "CbEmbedsOneParent" , inverse_of : :child
137
-
138
- def initialize ( callback_registry )
139
- @callback_registry = callback_registry
140
- super ( )
141
- end
142
-
143
- attr_accessor :callback_registry
144
-
145
- include CallbackTracking
146
104
end
147
105
148
106
class CbEmbedsManyParent
149
107
include Mongoid ::Document
108
+ include CallbackTracking
109
+ include RootInsertable
150
110
151
111
embeds_many :children , cascade_callbacks : true , class_name : "CbEmbedsManyChild" , inverse_of : :parent
152
-
153
- def initialize ( callback_registry )
154
- @callback_registry = callback_registry
155
- super ( )
156
- end
157
-
158
- attr_accessor :callback_registry
159
-
160
- def insert_as_root
161
- @callback_registry &.record_call ( self . class , :insert_into_database )
162
- super
163
- end
164
-
165
- include CallbackTracking
166
112
end
167
113
168
114
class CbEmbedsManyChild
169
115
include Mongoid ::Document
116
+ include CallbackTracking
170
117
171
118
embedded_in :parent , class_name : "CbEmbedsManyParent" , inverse_of : :children
172
-
173
- def initialize ( callback_registry )
174
- @callback_registry = callback_registry
175
- super ( )
176
- end
177
-
178
- attr_accessor :callback_registry
179
-
180
- include CallbackTracking
181
119
end
182
120
183
121
class CbParent
184
122
include Mongoid ::Document
185
-
186
- def initialize ( callback_registry )
187
- @callback_registry = callback_registry
188
- super ( )
189
- end
190
-
191
- attr_accessor :callback_registry
123
+ include CallbackTracking
192
124
193
125
embeds_many :cb_children
194
126
embeds_many :cb_cascaded_children , cascade_callbacks : true
195
-
196
- include CallbackTracking
127
+ embeds_many :cb_cascaded_nodes , cascade_callbacks : true , as : :parent
197
128
end
198
129
199
130
class CbChild
200
131
include Mongoid ::Document
132
+ include CallbackTracking
201
133
202
134
embedded_in :cb_parent
203
-
204
- def initialize ( callback_registry , options )
205
- @callback_registry = callback_registry
206
- super ( options )
207
- end
208
-
209
- attr_accessor :callback_registry
210
-
211
- include CallbackTracking
212
135
end
213
136
214
137
class CbCascadedChild
215
138
include Mongoid ::Document
139
+ include CallbackTracking
216
140
217
141
embedded_in :cb_parent
218
142
219
- def initialize ( callback_registry , options )
220
- @callback_registry = callback_registry
221
- super ( options )
222
- end
143
+ before_save :test_mongoid_state
223
144
224
- attr_accessor :callback_registry
145
+ private
146
+
147
+ # Helps test that cascading child callbacks have access to the Mongoid
148
+ # state objects; if the implementation uses fiber-local (instead of truly
149
+ # thread-local) variables, the related tests will fail because the
150
+ # cascading child callbacks use fibers to linearize the recursion.
151
+ def test_mongoid_state
152
+ Mongoid ::Threaded . stack ( 'interceptable' ) . push ( self )
153
+ end
154
+ end
225
155
156
+ class CbCascadedNode
157
+ include Mongoid ::Document
226
158
include CallbackTracking
159
+
160
+ embedded_in :parent , polymorphic : true
161
+
162
+ embeds_many :cb_cascaded_nodes , cascade_callbacks : true , as : :parent
227
163
end
228
164
end
229
165
0 commit comments