mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Merge pull request #726 from rails-api/json-api-include-with-nested-has-many
Bugfix: include nested has_many associations
This commit is contained in:
commit
7592e838ee
@ -77,10 +77,13 @@ module ActiveModel
|
||||
resource_path = [parent, resource].compact.join('.')
|
||||
if include_assoc? resource_path
|
||||
plural_name = resource.to_s.pluralize.to_sym
|
||||
attrs = attributes_for_serializer(serializer, @options)
|
||||
attrs = [attributes_for_serializer(serializer, @options)].flatten
|
||||
@top[:linked] ||= {}
|
||||
@top[:linked][plural_name] ||= []
|
||||
@top[:linked][plural_name].push attrs unless @top[:linked][plural_name].include? attrs
|
||||
|
||||
attrs.each do |attrs|
|
||||
@top[:linked][plural_name].push(attrs) unless @top[:linked][plural_name].include?(attrs)
|
||||
end
|
||||
end
|
||||
|
||||
serializer.each_association do |name, association, opts|
|
||||
@ -91,9 +94,19 @@ module ActiveModel
|
||||
private
|
||||
|
||||
def attributes_for_serializer(serializer, options)
|
||||
attributes = serializer.attributes(options)
|
||||
attributes[:id] = attributes[:id].to_s if attributes[:id]
|
||||
attributes
|
||||
if serializer.respond_to?(:each)
|
||||
result = []
|
||||
serializer.each do |object|
|
||||
attributes = object.attributes(options)
|
||||
attributes[:id] = attributes[:id].to_s if attributes[:id]
|
||||
result << attributes
|
||||
end
|
||||
else
|
||||
result = serializer.attributes(options)
|
||||
result[:id] = result[:id].to_s if result[:id]
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def include_assoc?(assoc)
|
||||
|
||||
@ -5,12 +5,15 @@ module ActionController
|
||||
class JsonApiLinkedTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def setup_post
|
||||
@role1 = Role.new(id: 1, name: 'admin')
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@author.posts = []
|
||||
@author.bio = nil
|
||||
@author.roles = [@role1]
|
||||
@author2 = Author.new(id: 2, name: 'Anonymous')
|
||||
@author2.posts = []
|
||||
@author2.bio = nil
|
||||
@author2.roles = []
|
||||
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||
@ -51,6 +54,13 @@ module ActionController
|
||||
end
|
||||
end
|
||||
|
||||
def render_resource_with_nested_has_many_include
|
||||
with_json_api_adapter do
|
||||
setup_post
|
||||
render json: @post, include: 'author,author.roles'
|
||||
end
|
||||
end
|
||||
|
||||
def render_collection_without_include
|
||||
with_json_api_adapter do
|
||||
setup_post
|
||||
@ -82,6 +92,22 @@ module ActionController
|
||||
assert_equal 'Steve K.', response['linked']['authors'].first['name']
|
||||
end
|
||||
|
||||
def test_render_resource_with_nested_has_many_include
|
||||
get :render_resource_with_nested_has_many_include
|
||||
response = JSON.parse(@response.body)
|
||||
expected_linked = {
|
||||
"authors" => [{
|
||||
"id" => "1",
|
||||
"name" => "Steve K."
|
||||
}],
|
||||
"roles"=>[{
|
||||
"id" => "1",
|
||||
"name" => "admin"
|
||||
}]
|
||||
}
|
||||
assert_equal expected_linked, response['linked']
|
||||
end
|
||||
|
||||
def test_render_resource_with_nested_include
|
||||
get :render_resource_with_nested_include
|
||||
response = JSON.parse(@response.body)
|
||||
|
||||
@ -8,6 +8,7 @@ module ActiveModel
|
||||
def setup
|
||||
@author = Author.new(name: 'Steve K.')
|
||||
@author.bio = nil
|
||||
@author.roles = nil
|
||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||
@author.posts = [@first_post, @second_post]
|
||||
|
||||
@ -16,6 +16,7 @@ module ActiveModel
|
||||
@second_post.author = @author
|
||||
@author.posts = [@first_post, @second_post]
|
||||
@author.bio = @bio
|
||||
@author.roles = []
|
||||
@bio.author = @author
|
||||
|
||||
@serializer = ArraySerializer.new([@first_post, @second_post])
|
||||
|
||||
8
test/fixtures/poro.rb
vendored
8
test/fixtures/poro.rb
vendored
@ -40,6 +40,7 @@ Comment = Class.new(Model)
|
||||
Author = Class.new(Model)
|
||||
Bio = Class.new(Model)
|
||||
Blog = Class.new(Model)
|
||||
Role = Class.new(Model)
|
||||
|
||||
PostSerializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :title, :body, :id
|
||||
@ -60,9 +61,16 @@ AuthorSerializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :id, :name
|
||||
|
||||
has_many :posts, embed: :ids
|
||||
has_many :roles, embed: :ids
|
||||
belongs_to :bio
|
||||
end
|
||||
|
||||
RoleSerializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :id, :name
|
||||
|
||||
belongs_to :author
|
||||
end
|
||||
|
||||
BioSerializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :id, :content
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ module ActiveModel
|
||||
def setup
|
||||
@author = Author.new(name: 'Steve K.')
|
||||
@author.bio = nil
|
||||
@author.roles = []
|
||||
@post = Post.new({ title: 'New Post', body: 'Body' })
|
||||
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
||||
@post.comments = [@comment]
|
||||
@ -42,6 +43,7 @@ module ActiveModel
|
||||
def test_has_many
|
||||
assert_equal(
|
||||
{ posts: { type: :has_many, options: { embed: :ids } },
|
||||
roles: { type: :has_many, options: { embed: :ids } },
|
||||
bio: { type: :belongs_to, options: {} } },
|
||||
@author_serializer.class._associations
|
||||
)
|
||||
@ -52,6 +54,9 @@ module ActiveModel
|
||||
elsif name == :bio
|
||||
assert_equal({}, options)
|
||||
assert_nil serializer
|
||||
elsif name == :roles
|
||||
assert_equal({embed: :ids}, options)
|
||||
assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
|
||||
else
|
||||
flunk "Unknown association: #{name}"
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user