Skip to content

Commit

Permalink
Prevent creation of unnecessary fieldset(mirror changes from rails-ap…
Browse files Browse the repository at this point in the history
…i#2370)

* refactor: instance_options[:fieldset] must be nil as it's not listed in ADAPTER_OPTION_KEYS
  • Loading branch information
liijunwei committed Aug 12, 2023
1 parent 9fa9373 commit eeb1090
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
7 changes: 4 additions & 3 deletions lib/active_model/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,10 @@ def associations(include_directive = ActiveModelSerializers.default_include_dire
def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance)
adapter_options ||= {}
options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options)
if (fieldset = adapter_options[:fieldset])
options[:fields] = fieldset.fields_for(json_key)
end

fieldset = adapter_options[:fieldset]
options[:fields] = fieldset.fields_for(json_key) if fieldset

resource = attributes_hash(adapter_options, options, adapter_instance)
relationships = associations_hash(adapter_options, options, adapter_instance)
resource.merge(relationships)
Expand Down
10 changes: 8 additions & 2 deletions lib/active_model_serializers/adapter/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ module Adapter
class Attributes < Base
def initialize(*)
super
instance_options[:fieldset] ||= ActiveModel::Serializer::Fieldset.new(fields_to_fieldset(instance_options.delete(:fields)))

fields = instance_options.delete(:fields)
fieldset = fields_to_fieldset(fields)
instance_options[:fieldset] = ActiveModel::Serializer::Fieldset.new(fieldset) if fieldset
end

def serializable_hash(options = nil)
Expand All @@ -19,16 +22,19 @@ def serializable_hash(options = nil)
private

def fields_to_fieldset(fields)
return fields if fields.nil?
return if fields.nil?

resource_fields = []
relationship_fields = {}

fields.each do |field|
case field
when Symbol, String then resource_fields << field
when Hash then relationship_fields.merge!(field)
else fail ArgumentError, "Unknown conversion of fields to fieldset: '#{field.inspect}' in '#{fields.inspect}'"
end
end

relationship_fields.merge!(serializer.json_key.to_sym => resource_fields)
end
end
Expand Down
6 changes: 4 additions & 2 deletions lib/active_model_serializers/adapter/json_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ def self.fragment_cache(cached_hash, non_cached_hash, root = true)
def initialize(serializer, options = {})
super
@include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
option_fields = options.delete(:fields)
@fieldset = ActiveModel::Serializer::Fieldset.new(option_fields) if option_fields
end

# {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure}
Expand Down Expand Up @@ -348,7 +349,8 @@ def data_for(serializer, include_slice)
data.tap do |resource_object|
next if resource_object.nil?
# NOTE(BF): the attributes are cached above, separately from the relationships, below.
requested_associations = fieldset.fields_for(resource_object[:type]) || '*'
requested_fields = fieldset && fieldset.fields_for(resource_object[:type])
requested_associations = requested_fields || '*'
relationships = relationships_for(serializer, requested_associations, include_slice)
resource_object[:relationships] = relationships if relationships.any?
end
Expand Down

0 comments on commit eeb1090

Please sign in to comment.