@@ -8,10 +8,11 @@ class CollectionSerializer
88 attr_reader :object , :root
99
1010 def initialize ( resources , options = { } )
11- @root = options [ :root ]
12- @object = resources
11+ @object = resources
12+ @options = options
13+ @root = options [ :root ]
14+ serializer_context_class = options . fetch ( :serializer_context_class , ActiveModel ::Serializer )
1315 @serializers = resources . map do |resource |
14- serializer_context_class = options . fetch ( :serializer_context_class , ActiveModel ::Serializer )
1516 serializer_class = options . fetch ( :serializer ) { serializer_context_class . serializer_for ( resource ) }
1617
1718 if serializer_class . nil? # rubocop:disable Style/GuardClause
@@ -26,9 +27,28 @@ def success?
2627 true
2728 end
2829
30+ # TODO: unify naming of root, json_key, and _type. Right now, a serializer's
31+ # json_key comes from the root option or the object's model name, by default.
32+ # But, if a dev defines a custom `json_key` method with an explicit value,
33+ # we have no simple way to know that it is safe to call that instance method.
34+ # (which is really a class property at this point, anyhow).
35+ # rubocop:disable Metrics/CyclomaticComplexity
36+ # Disabling cop since it's good to highlight the complexity of this method by
37+ # including all the logic right here.
2938 def json_key
30- root || derived_root
39+ return root if root
40+ # 1. get from options[:serializer] for empty resource collection
41+ key = object . empty? &&
42+ ( explicit_serializer_class = options [ :serializer ] ) &&
43+ explicit_serializer_class . _type
44+ # 2. get from first serializer instance in collection
45+ key ||= ( serializer = serializers . first ) && serializer . json_key
46+ # 3. get from collection name, if a named collection
47+ key ||= object . respond_to? ( :name ) ? object . name && object . name . underscore : nil
48+ # 4. key may be nil for empty collection and no serializer option
49+ key && key . pluralize
3150 end
51+ # rubocop:enable Metrics/CyclomaticComplexity
3252
3353 def paginated?
3454 object . respond_to? ( :current_page ) &&
@@ -38,14 +58,7 @@ def paginated?
3858
3959 protected
4060
41- attr_reader :serializers
42-
43- private
44-
45- def derived_root
46- key = serializers . first . try ( :json_key ) || object . try ( :name ) . try ( :underscore )
47- key . try ( :pluralize )
48- end
61+ attr_reader :serializers , :options
4962 end
5063 end
5164end
0 commit comments