@@ -213,6 +213,37 @@ def test_no_href_in_vanilla_reflection
213
213
end
214
214
assert_match ( /undefined method `href'/ , exception . message )
215
215
end
216
+
217
+ def test_mutating_reflection_block_is_not_thread_safe
218
+ serializer_class = Class . new ( ActiveModel ::Serializer ) do
219
+ has_one :blog do
220
+ meta ( id : object . blog . id )
221
+ end
222
+ end
223
+ model1_meta = @expected_meta
224
+ # Evaluate reflection meta for model with id 1
225
+ serializer_instance = serializer_class . new ( @model , @instance_options )
226
+ reflection = serializer_class . _reflections . fetch ( :blog )
227
+ assert_nil reflection . instance_variable_get ( :@_meta )
228
+ association = reflection . build_association ( serializer_instance , @instance_options )
229
+ assert_equal model1_meta , association . meta
230
+ assert_equal model1_meta , reflection . instance_variable_get ( :@_meta )
231
+
232
+ model2_meta = @expected_meta . merge ( id : 2 )
233
+ # Evaluate reflection meta for model with id 2
234
+ @model . blog . id = 2
235
+ assert_equal 2 , @model . blog . id # sanity check
236
+ serializer_instance = serializer_class . new ( @model , @instance_options )
237
+ reflection = serializer_class . _reflections . fetch ( :blog )
238
+
239
+ # WARN: Thread-safety issue
240
+ # Before the reflection is evaluated, it has the value from the previous evaluation
241
+ assert_equal model1_meta , reflection . instance_variable_get ( :@_meta )
242
+
243
+ association = reflection . build_association ( serializer_instance , @instance_options )
244
+ assert_equal model2_meta , association . meta
245
+ assert_equal model2_meta , reflection . instance_variable_get ( :@_meta )
246
+ end
216
247
end
217
248
end
218
249
end
0 commit comments