Fix JSON:API: for_type_and_id should always inflect_type

Should Serializer._type ever be inflected?
Right now, it won't be, but association.serializer._type will be inflected.

That's the current behavior.
This commit is contained in:
Benjamin Fleischer 2017-10-29 19:40:04 -05:00
parent cf29db34c6
commit a0de45a4d8
2 changed files with 26 additions and 16 deletions

View File

@ -43,17 +43,16 @@ module ActiveModelSerializers
end end
def data_for_one(association) def data_for_one(association)
if association.belongs_to? && if belongs_to_id_on_self?(association)
parent_serializer.object.respond_to?(association.reflection.foreign_key)
id = parent_serializer.read_attribute_for_serialization(association.reflection.foreign_key) id = parent_serializer.read_attribute_for_serialization(association.reflection.foreign_key)
if association.polymorphic? type =
# We can't infer resource type for polymorphic relationships from the serializer. if association.polymorphic?
# We can ONLY know a polymorphic resource type by inspecting each resource. # We can't infer resource type for polymorphic relationships from the serializer.
serializer = association.lazy_association.serializer # We can ONLY know a polymorphic resource type by inspecting each resource.
type = serializer.json_key association.lazy_association.serializer.json_key
else else
type = association.reflection.type.to_s association.reflection.type.to_s
end end
ResourceIdentifier.for_type_with_id(type, id, serializable_resource_options) ResourceIdentifier.for_type_with_id(type, id, serializable_resource_options)
else else
# TODO(BF): Process relationship without evaluating lazy_association # TODO(BF): Process relationship without evaluating lazy_association
@ -93,6 +92,11 @@ module ActiveModelSerializers
meta = association.meta meta = association.meta
meta.respond_to?(:call) ? parent_serializer.instance_eval(&meta) : meta meta.respond_to?(:call) ? parent_serializer.instance_eval(&meta) : meta
end end
def belongs_to_id_on_self?(association)
association.belongs_to? &&
parent_serializer.object.respond_to?(association.reflection.foreign_key)
end
end end
end end
end end

View File

@ -9,6 +9,7 @@ module ActiveModelSerializers
def self.for_type_with_id(type, id, options) def self.for_type_with_id(type, id, options)
return nil if id.blank? return nil if id.blank?
type = inflect_type(type)
{ {
id: id.to_s, id: id.to_s,
type: type_for(:no_class_needed, type, options) type: type_for(:no_class_needed, type, options)
@ -17,13 +18,17 @@ module ActiveModelSerializers
def self.raw_type_from_serializer_object(object) def self.raw_type_from_serializer_object(object)
class_name = object.class.name # should use model_name class_name = object.class.name # should use model_name
serializer_type = class_name.underscore raw_type = class_name.underscore
raw_type = inflect_type(raw_type)
raw_type
.gsub!('/'.freeze, ActiveModelSerializers.config.jsonapi_namespace_separator)
raw_type
end
def self.inflect_type(type)
singularize = ActiveModelSerializers.config.jsonapi_resource_type == :singular singularize = ActiveModelSerializers.config.jsonapi_resource_type == :singular
inflection = singularize ? :singularize : :pluralize inflection = singularize ? :singularize : :pluralize
serializer_type = ActiveSupport::Inflector.public_send(inflection, serializer_type) ActiveSupport::Inflector.public_send(inflection, type)
serializer_type
.gsub!('/'.freeze, ActiveModelSerializers.config.jsonapi_namespace_separator)
serializer_type
end end
# {http://jsonapi.org/format/#document-resource-identifier-objects Resource Identifier Objects} # {http://jsonapi.org/format/#document-resource-identifier-objects Resource Identifier Objects}
@ -44,7 +49,8 @@ module ActiveModelSerializers
private private
def type_for(serializer, transform_options) def type_for(serializer, transform_options)
self.class.type_for(serializer, serializer._type, transform_options) serializer_type = serializer._type
self.class.type_for(serializer, serializer_type, transform_options)
end end
def id_for(serializer) def id_for(serializer)