mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-24 14:56:50 +00:00
Provide a schema for a serializer
This commit is contained in:
parent
4efb1f33ab
commit
0f4b61fbcf
@ -158,6 +158,58 @@ module ActiveModel
|
|||||||
associate(Associations::HasOne, attrs)
|
associate(Associations::HasOne, attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return a schema hash for the current serializer. This information
|
||||||
|
# can be used to generate clients for the serialized output.
|
||||||
|
#
|
||||||
|
# The schema hash has two keys: +attributes+ and +associations+.
|
||||||
|
#
|
||||||
|
# The +attributes+ hash looks like this:
|
||||||
|
#
|
||||||
|
# { :name => :string, :age => :integer }
|
||||||
|
#
|
||||||
|
# The +associations+ hash looks like this:
|
||||||
|
#
|
||||||
|
# { :posts => { :has_many => :posts } }
|
||||||
|
#
|
||||||
|
# If :as is used:
|
||||||
|
#
|
||||||
|
# class PostsSerializer < ActiveModel::Serializer
|
||||||
|
# has_many :my_posts, :as => :posts
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# the hash looks like this:
|
||||||
|
#
|
||||||
|
# { :my_posts => { :has_many => :posts }
|
||||||
|
#
|
||||||
|
# This information is extracted from the serializer's model class,
|
||||||
|
# which is provided by +SerializerClass.model_class+.
|
||||||
|
#
|
||||||
|
# The schema method uses the +columns_hash+ and +reflect_on_association+
|
||||||
|
# methods, provided by default by ActiveRecord. You can implement these
|
||||||
|
# methods on your custom models if you want the serializer's schema method
|
||||||
|
# to work.
|
||||||
|
def schema
|
||||||
|
klass = model_class
|
||||||
|
columns = klass.columns_hash
|
||||||
|
|
||||||
|
attrs = _attributes.inject({}) do |hash, name|
|
||||||
|
column = columns[name]
|
||||||
|
hash.merge name => column[:type]
|
||||||
|
end
|
||||||
|
|
||||||
|
associations = _associations.inject({}) do |hash, association|
|
||||||
|
model_association = klass.reflect_on_association(association.key)
|
||||||
|
hash.merge association.key => { model_association.macro => model_association.name }
|
||||||
|
end
|
||||||
|
|
||||||
|
{ :attributes => attrs, :associations => associations }
|
||||||
|
end
|
||||||
|
|
||||||
|
# The model class associated with this serializer.
|
||||||
|
def model_class
|
||||||
|
name.sub(/Serializer$/, '')
|
||||||
|
end
|
||||||
|
|
||||||
# Define how associations should be embedded.
|
# Define how associations should be embedded.
|
||||||
#
|
#
|
||||||
# embed :objects # Embed associations as full objects
|
# embed :objects # Embed associations as full objects
|
||||||
|
|||||||
@ -508,4 +508,67 @@ class SerializerTest < ActiveModel::TestCase
|
|||||||
}
|
}
|
||||||
}, serializer.as_json)
|
}, serializer.as_json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def setup_model
|
||||||
|
Class.new do
|
||||||
|
class << self
|
||||||
|
def columns_hash
|
||||||
|
{ :name => { :type => :string }, :age => { :type => :integer } }
|
||||||
|
end
|
||||||
|
|
||||||
|
def reflect_on_association(name)
|
||||||
|
case name
|
||||||
|
when :posts
|
||||||
|
Struct.new(:macro, :name).new(:has_many, :posts)
|
||||||
|
when :parent
|
||||||
|
Struct.new(:macro, :name).new(:belongs_to, :parent)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_schema
|
||||||
|
model = setup_model
|
||||||
|
|
||||||
|
serializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
class << self; self; end.class_eval do
|
||||||
|
define_method(:model_class) do model end
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes :name, :age
|
||||||
|
has_many :posts, :serializer => Class.new
|
||||||
|
has_one :parent, :serializer => Class.new
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal serializer.schema, {
|
||||||
|
:attributes => { :name => :string, :age => :integer },
|
||||||
|
:associations => {
|
||||||
|
:posts => { :has_many => :posts },
|
||||||
|
:parent => { :belongs_to => :parent }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_schema_with_as
|
||||||
|
model = setup_model
|
||||||
|
|
||||||
|
serializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
class << self; self; end.class_eval do
|
||||||
|
define_method(:model_class) do model end
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes :name, :age
|
||||||
|
has_many :my_posts, :as => :posts, :serializer => Class.new
|
||||||
|
has_one :my_parent, :as => :parent, :serializer => Class.new
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal serializer.schema, {
|
||||||
|
:attributes => { :name => :string, :age => :integer },
|
||||||
|
:associations => {
|
||||||
|
:my_posts => { :has_many => :posts },
|
||||||
|
:my_parent => { :belongs_to => :parent }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user