mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-24 23:06:50 +00:00
Merge pull request #2211 from rails-api/polymorphic_relationships_require_serializer_instance
JSON:API relationship tests no longer show v0.10.5 regression
This commit is contained in:
commit
e3480345e3
@ -43,10 +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)
|
||||||
type = association.reflection.type.to_s
|
type =
|
||||||
|
if association.polymorphic?
|
||||||
|
# We can't infer resource type for polymorphic relationships from the serializer.
|
||||||
|
# We can ONLY know a polymorphic resource type by inspecting each resource.
|
||||||
|
association.lazy_association.serializer.json_key
|
||||||
|
else
|
||||||
|
association.reflection.type.to_s
|
||||||
|
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
|
||||||
@ -86,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
|
||||||
|
|||||||
@ -2,34 +2,35 @@ module ActiveModelSerializers
|
|||||||
module Adapter
|
module Adapter
|
||||||
class JsonApi
|
class JsonApi
|
||||||
class ResourceIdentifier
|
class ResourceIdentifier
|
||||||
def self.type_for(class_name, serializer_type = nil, transform_options = {})
|
def self.type_for(serializer, serializer_type = nil, transform_options = {})
|
||||||
if serializer_type
|
raw_type = serializer_type ? serializer_type : raw_type_from_serializer_object(serializer.object)
|
||||||
raw_type = serializer_type
|
|
||||||
else
|
|
||||||
inflection =
|
|
||||||
if ActiveModelSerializers.config.jsonapi_resource_type == :singular
|
|
||||||
:singularize
|
|
||||||
else
|
|
||||||
:pluralize
|
|
||||||
end
|
|
||||||
|
|
||||||
raw_type = class_name.underscore
|
|
||||||
raw_type = ActiveSupport::Inflector.public_send(inflection, raw_type)
|
|
||||||
raw_type
|
|
||||||
.gsub!('/'.freeze, ActiveModelSerializers.config.jsonapi_namespace_separator)
|
|
||||||
raw_type
|
|
||||||
end
|
|
||||||
JsonApi.send(:transform_key_casing!, raw_type, transform_options)
|
JsonApi.send(:transform_key_casing!, raw_type, transform_options)
|
||||||
end
|
end
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.raw_type_from_serializer_object(object)
|
||||||
|
class_name = object.class.name # should use model_name
|
||||||
|
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
|
||||||
|
inflection = singularize ? :singularize : :pluralize
|
||||||
|
ActiveSupport::Inflector.public_send(inflection, type)
|
||||||
|
end
|
||||||
|
|
||||||
# {http://jsonapi.org/format/#document-resource-identifier-objects Resource Identifier Objects}
|
# {http://jsonapi.org/format/#document-resource-identifier-objects Resource Identifier Objects}
|
||||||
def initialize(serializer, options)
|
def initialize(serializer, options)
|
||||||
@id = id_for(serializer)
|
@id = id_for(serializer)
|
||||||
@ -48,7 +49,8 @@ module ActiveModelSerializers
|
|||||||
private
|
private
|
||||||
|
|
||||||
def type_for(serializer, transform_options)
|
def type_for(serializer, transform_options)
|
||||||
self.class.type_for(serializer.object.class.name, 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)
|
||||||
|
|||||||
@ -165,6 +165,53 @@ module ActiveModel
|
|||||||
|
|
||||||
assert_equal(expected, serialization(@picture, :json_api))
|
assert_equal(expected, serialization(@picture, :json_api))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_json_api_serialization_with_polymorphic_belongs_to
|
||||||
|
expected = {
|
||||||
|
data: {
|
||||||
|
id: '1',
|
||||||
|
type: 'poly-tags',
|
||||||
|
attributes: { phrase: 'foo' },
|
||||||
|
relationships: {
|
||||||
|
:"object-tags" => {
|
||||||
|
data: [
|
||||||
|
{ id: '1', type: 'object-tags' },
|
||||||
|
{ id: '5', type: 'object-tags' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
included: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
type: 'object-tags',
|
||||||
|
relationships: {
|
||||||
|
taggable: {
|
||||||
|
data: { id: '42', type: 'employees' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '42',
|
||||||
|
type: 'employees'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '5',
|
||||||
|
type: 'object-tags',
|
||||||
|
relationships: {
|
||||||
|
taggable: {
|
||||||
|
data: { id: '1', type: 'pictures' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
type: 'pictures'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
assert_equal(expected, tag_serialization(:json_api))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
4
test/fixtures/active_record.rb
vendored
4
test/fixtures/active_record.rb
vendored
@ -89,7 +89,7 @@ class ObjectTag < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
class PolymorphicObjectTagSerializer < ActiveModel::Serializer
|
class PolymorphicObjectTagSerializer < ActiveModel::Serializer
|
||||||
attributes :id
|
attributes :id
|
||||||
has_many :taggable, serializer: PolymorphicSimpleSerializer, polymorphic: true
|
belongs_to :taggable, serializer: PolymorphicSimpleSerializer, polymorphic: true
|
||||||
end
|
end
|
||||||
|
|
||||||
class PolyTag < ActiveRecord::Base
|
class PolyTag < ActiveRecord::Base
|
||||||
@ -109,5 +109,5 @@ class PolymorphicHasManySerializer < ActiveModel::Serializer
|
|||||||
end
|
end
|
||||||
class PolymorphicBelongsToSerializer < ActiveModel::Serializer
|
class PolymorphicBelongsToSerializer < ActiveModel::Serializer
|
||||||
attributes :id, :title
|
attributes :id, :title
|
||||||
has_one :imageable, serializer: PolymorphicHasManySerializer, polymorphic: true
|
belongs_to :imageable, serializer: PolymorphicHasManySerializer, polymorphic: true
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user