@@ -47,8 +47,6 @@ class Serializer
47
47
#
48
48
# So you can inspect reflections in your Adapters.
49
49
class Reflection < Field
50
- REFLECTION_OPTIONS = %i( key links polymorphic meta serializer virtual_value namespace ) . freeze
51
-
52
50
def initialize ( *)
53
51
super
54
52
options [ :links ] = { }
@@ -125,92 +123,6 @@ def collection?
125
123
false
126
124
end
127
125
128
- # Build association. This method is used internally to
129
- # build serializer's association by its reflection.
130
- #
131
- # @param [Serializer] parent_serializer for given association
132
- # @param [Hash{Symbol => Object}] parent_serializer_options
133
- #
134
- # @example
135
- # # Given the following serializer defined:
136
- # class PostSerializer < ActiveModel::Serializer
137
- # has_many :comments, serializer: CommentSummarySerializer
138
- # end
139
- #
140
- # # Then you instantiate your serializer
141
- # post_serializer = PostSerializer.new(post, foo: 'bar') #
142
- # # to build association for comments you need to get reflection
143
- # comments_reflection = PostSerializer._reflections.detect { |r| r.name == :comments }
144
- # # and #build_association
145
- # comments_reflection.build_association(post_serializer, foo: 'bar')
146
- #
147
- # @api private
148
- def build_association ( parent_serializer , parent_serializer_options , include_slice = { } )
149
- reflection_options = settings . merge ( include_data : include_data? ( include_slice ) ) unless block?
150
-
151
- association_value = value ( parent_serializer , include_slice )
152
- serializer_class = build_serializer_class ( association_value , parent_serializer , parent_serializer_options [ :namespace ] )
153
-
154
- reflection_options ||= settings . merge ( include_data : include_data? ( include_slice ) ) # Needs to be after association_value is evaluated unless reflection.block.nil?
155
-
156
- if serializer_class
157
- if ( serializer = build_serializer! ( association_value , serializer_class , parent_serializer , parent_serializer_options ) )
158
- reflection_options [ :serializer ] = serializer
159
- else
160
- # BUG: per #2027, JSON API resource relationships are only id and type, and hence either
161
- # *require* a serializer or we need to be a little clever about figuring out the id/type.
162
- # In either case, returning the raw virtual value will almost always be incorrect.
163
- #
164
- # Should be reflection_options[:virtual_value] or adapter needs to figure out what to do
165
- # with an object that is non-nil and has no defined serializer.
166
- reflection_options [ :virtual_value ] = association_value . try ( :as_json ) || association_value
167
- end
168
- elsif !association_value . nil? && !association_value . instance_of? ( Object )
169
- reflection_options [ :virtual_value ] = association_value
170
- end
171
-
172
- association_block = nil
173
- reflection_options [ :reflection ] = self
174
- reflection_options [ :parent_serializer ] = parent_serializer
175
- reflection_options [ :parent_serializer_options ] = parent_serializer_options
176
- reflection_options [ :include_slice ] = include_slice
177
- Association . new ( name , reflection_options , block )
178
- end
179
-
180
- protected
181
-
182
- # used in instance exec
183
- attr_accessor :object , :scope
184
-
185
- def settings
186
- options . dup . reject { |k , _ | !REFLECTION_OPTIONS . include? ( k ) }
187
- end
188
-
189
- # Evaluation of the reflection.block will mutate options.
190
- # So, the settings cannot be used until the block is evaluated.
191
- # This means that each time the block is evaluated, it may set a new
192
- # value in the reflection instance. This is not thread-safe.
193
- # @example
194
- # has_many :likes do
195
- # meta liked: object.likes.any?
196
- # include_data: object.loaded?
197
- # end
198
- def block?
199
- !block . nil?
200
- end
201
-
202
- def serializer?
203
- options . key? ( :serializer )
204
- end
205
-
206
- def serializer
207
- options [ :serializer ]
208
- end
209
-
210
- def namespace
211
- options [ :namespace ]
212
- end
213
-
214
126
def include_data? ( include_slice )
215
127
include_data_setting = options [ :include_data_setting ]
216
128
case include_data_setting
@@ -238,42 +150,39 @@ def value(serializer, include_slice)
238
150
end
239
151
end
240
152
241
- def build_serializer! ( association_value , serializer_class , parent_serializer , parent_serializer_options )
242
- if collection?
243
- build_association_collection_serializer ( parent_serializer , parent_serializer_options , association_value , serializer_class )
244
- else
245
- build_association_serializer ( parent_serializer , parent_serializer_options , association_value , serializer_class )
246
- end
247
- end
248
-
249
- def build_serializer_class ( association_value , parent_serializer , parent_serializer_namespace_option )
250
- serializer_for_options = {
251
- # Pass the parent's namespace onto the child serializer
252
- namespace : namespace || parent_serializer_namespace_option
153
+ # Build association. This method is used internally to
154
+ # build serializer's association by its reflection.
155
+ #
156
+ # @param [Serializer] parent_serializer for given association
157
+ # @param [Hash{Symbol => Object}] parent_serializer_options
158
+ #
159
+ # @example
160
+ # # Given the following serializer defined:
161
+ # class PostSerializer < ActiveModel::Serializer
162
+ # has_many :comments, serializer: CommentSummarySerializer
163
+ # end
164
+ #
165
+ # # Then you instantiate your serializer
166
+ # post_serializer = PostSerializer.new(post, foo: 'bar') #
167
+ # # to build association for comments you need to get reflection
168
+ # comments_reflection = PostSerializer._reflections.detect { |r| r.name == :comments }
169
+ # # and #build_association
170
+ # comments_reflection.build_association(post_serializer, foo: 'bar')
171
+ #
172
+ # @api private
173
+ def build_association ( parent_serializer , parent_serializer_options , include_slice = { } )
174
+ association_options = {
175
+ parent_serializer : parent_serializer ,
176
+ parent_serializer_options : parent_serializer_options ,
177
+ include_slice : include_slice
253
178
}
254
- serializer_for_options [ :serializer ] = serializer if serializer?
255
- parent_serializer . class . serializer_for ( association_value , serializer_for_options )
179
+ Association . new ( self , association_options )
256
180
end
257
181
258
- # NOTE(BF): This serializer throw/catch should only happen when the serializer is a collection
259
- # serializer.
260
- #
261
- # @return [ActiveModel::Serializer, nil]
262
- def build_association_collection_serializer ( parent_serializer , parent_serializer_options , association_value , serializer_class )
263
- catch ( :no_serializer ) do
264
- build_association_serializer ( parent_serializer , parent_serializer_options , association_value , serializer_class )
265
- end
266
- end
182
+ protected
267
183
268
- # @return [ActiveModel::Serializer, nil]
269
- def build_association_serializer ( parent_serializer , parent_serializer_options , association_value , serializer_class )
270
- # Make all the parent serializer instance options available to associations
271
- # except ActiveModelSerializers-specific ones we don't want.
272
- serializer_options = parent_serializer_options . except ( :serializer )
273
- serializer_options [ :serializer_context_class ] = parent_serializer . class
274
- serializer_options [ :serializer ] = serializer if serializer
275
- serializer_class . new ( association_value , serializer_options )
276
- end
184
+ # used in instance exec
185
+ attr_accessor :object , :scope
277
186
end
278
187
end
279
188
end
0 commit comments