mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Merge pull request #1857 from bf4/smarter_association_id_lookup
Smarter association id lookup-- no db hit on belongs_to for id-only
This commit is contained in:
commit
7d0f4e0a61
@ -38,6 +38,10 @@ module ActiveModel
|
|||||||
reflection.options[:meta]
|
reflection.options[:meta]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def belongs_to?
|
||||||
|
reflection.foreign_key_on == :self
|
||||||
|
end
|
||||||
|
|
||||||
def polymorphic?
|
def polymorphic?
|
||||||
true == reflection_options[:polymorphic]
|
true == reflection_options[:polymorphic]
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,6 +2,10 @@ module ActiveModel
|
|||||||
class Serializer
|
class Serializer
|
||||||
# @api private
|
# @api private
|
||||||
class BelongsToReflection < Reflection
|
class BelongsToReflection < Reflection
|
||||||
|
# @api private
|
||||||
|
def foreign_key_on
|
||||||
|
:self
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -47,11 +47,23 @@ module ActiveModel
|
|||||||
#
|
#
|
||||||
# So you can inspect reflections in your Adapters.
|
# So you can inspect reflections in your Adapters.
|
||||||
class Reflection < Field
|
class Reflection < Field
|
||||||
|
attr_reader :foreign_key, :type
|
||||||
|
|
||||||
def initialize(*)
|
def initialize(*)
|
||||||
super
|
super
|
||||||
options[:links] = {}
|
options[:links] = {}
|
||||||
options[:include_data_setting] = Serializer.config.include_data_default
|
options[:include_data_setting] = Serializer.config.include_data_default
|
||||||
options[:meta] = nil
|
options[:meta] = nil
|
||||||
|
@type = options.fetch(:type) do
|
||||||
|
class_name = options.fetch(:class_name, name.to_s.camelize.singularize)
|
||||||
|
class_name.underscore.pluralize.to_sym
|
||||||
|
end
|
||||||
|
@foreign_key =
|
||||||
|
if collection?
|
||||||
|
"#{name.to_s.singularize}_ids".to_sym
|
||||||
|
else
|
||||||
|
"#{name}_id".to_sym
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# @api public
|
# @api public
|
||||||
@ -150,6 +162,11 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
def foreign_key_on
|
||||||
|
:related
|
||||||
|
end
|
||||||
|
|
||||||
# Build association. This method is used internally to
|
# Build association. This method is used internally to
|
||||||
# build serializer's association by its reflection.
|
# build serializer's association by its reflection.
|
||||||
#
|
#
|
||||||
|
|||||||
@ -43,6 +43,12 @@ module ActiveModelSerializers
|
|||||||
end
|
end
|
||||||
|
|
||||||
def data_for_one(association)
|
def data_for_one(association)
|
||||||
|
if association.belongs_to? &&
|
||||||
|
parent_serializer.object.respond_to?(association.reflection.foreign_key)
|
||||||
|
id = parent_serializer.object.send(association.reflection.foreign_key)
|
||||||
|
type = association.reflection.type.to_s
|
||||||
|
ResourceIdentifier.for_type_with_id(type, id, serializable_resource_options)
|
||||||
|
else
|
||||||
# TODO(BF): Process relationship without evaluating lazy_association
|
# TODO(BF): Process relationship without evaluating lazy_association
|
||||||
serializer = association.lazy_association.serializer
|
serializer = association.lazy_association.serializer
|
||||||
if (virtual_value = association.virtual_value)
|
if (virtual_value = association.virtual_value)
|
||||||
@ -53,6 +59,7 @@ module ActiveModelSerializers
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def data_for_many(association)
|
def data_for_many(association)
|
||||||
# TODO(BF): Process relationship without evaluating lazy_association
|
# TODO(BF): Process relationship without evaluating lazy_association
|
||||||
|
|||||||
@ -22,6 +22,13 @@ module ActiveModelSerializers
|
|||||||
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)
|
||||||
|
{
|
||||||
|
id: id.to_s,
|
||||||
|
type: type_for(:no_class_needed, type, options)
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
|||||||
@ -137,6 +137,34 @@ module ActiveModel
|
|||||||
assert expected_association_keys.include? :site
|
assert expected_association_keys.include? :site
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class BelongsToBlogModel < ::Model
|
||||||
|
attributes :id, :title
|
||||||
|
associations :blog
|
||||||
|
end
|
||||||
|
class BelongsToBlogModelSerializer < ActiveModel::Serializer
|
||||||
|
type :posts
|
||||||
|
belongs_to :blog
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_belongs_to_doesnt_load_record
|
||||||
|
attributes = { id: 1, title: 'Belongs to Blog', blog: Blog.new(id: 5) }
|
||||||
|
post = BelongsToBlogModel.new(attributes)
|
||||||
|
class << post
|
||||||
|
def blog
|
||||||
|
fail 'should use blog_id'
|
||||||
|
end
|
||||||
|
|
||||||
|
def blog_id
|
||||||
|
5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
actual = serializable(post, adapter: :json_api, serializer: BelongsToBlogModelSerializer).as_json
|
||||||
|
expected = { data: { id: '1', type: 'posts', relationships: { blog: { data: { id: '5', type: 'blogs' } } } } }
|
||||||
|
|
||||||
|
assert_equal expected, actual
|
||||||
|
end
|
||||||
|
|
||||||
class InlineAssociationTestPostSerializer < ActiveModel::Serializer
|
class InlineAssociationTestPostSerializer < ActiveModel::Serializer
|
||||||
has_many :comments
|
has_many :comments
|
||||||
has_many :comments, key: :last_comments do
|
has_many :comments, key: :last_comments do
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user