mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
Fix infinite recursion
The method for testing whether to include an association was causing an infinite loop when two models referenced each other.
This commit is contained in:
parent
95d122046d
commit
d97b2f5005
@ -83,11 +83,9 @@ module ActiveModel
|
|||||||
@top[:linked][plural_name].push attrs unless @top[:linked][plural_name].include? attrs
|
@top[:linked][plural_name].push attrs unless @top[:linked][plural_name].include? attrs
|
||||||
end
|
end
|
||||||
|
|
||||||
unless serializer.respond_to?(:each)
|
serializer.each_association do |name, association, opts|
|
||||||
serializer.each_association do |name, association, opts|
|
add_linked(name, association, resource_path) if association
|
||||||
add_linked(name, association, resource) if association
|
end if include_nested_assoc? resource_path
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -98,8 +96,20 @@ module ActiveModel
|
|||||||
attributes
|
attributes
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_assoc? assoc
|
def include_assoc?(assoc)
|
||||||
@options[:include] && @options[:include].split(',').include?(assoc.to_s)
|
return false unless @options[:include]
|
||||||
|
check_assoc("#{assoc}$")
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_nested_assoc?(assoc)
|
||||||
|
return false unless @options[:include]
|
||||||
|
check_assoc("#{assoc}.")
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_assoc(assoc)
|
||||||
|
@options[:include].split(',').any? do |s|
|
||||||
|
s.match(/^#{assoc.gsub('.', '\.')}/)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -7,8 +7,10 @@ module ActionController
|
|||||||
def setup_post
|
def setup_post
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@author.posts = []
|
@author.posts = []
|
||||||
|
@author.bio = nil
|
||||||
@author2 = Author.new(id: 2, name: 'Anonymous')
|
@author2 = Author.new(id: 2, name: 'Anonymous')
|
||||||
@author2.posts = []
|
@author2.posts = []
|
||||||
|
@author2.bio = nil
|
||||||
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
||||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||||
|
|||||||
@ -7,6 +7,7 @@ module ActiveModel
|
|||||||
class BelongsToTest < Minitest::Test
|
class BelongsToTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
|
@author.bio = nil
|
||||||
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
||||||
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
|
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
|
|||||||
@ -7,6 +7,7 @@ module ActiveModel
|
|||||||
class CollectionTest < Minitest::Test
|
class CollectionTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
|
@author.bio = nil
|
||||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||||
@first_post.comments = []
|
@first_post.comments = []
|
||||||
|
|||||||
@ -7,6 +7,7 @@ module ActiveModel
|
|||||||
class HasManyEmbedIdsTest < Minitest::Test
|
class HasManyEmbedIdsTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(name: 'Steve K.')
|
@author = Author.new(name: 'Steve K.')
|
||||||
|
@author.bio = nil
|
||||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||||
@author.posts = [@first_post, @second_post]
|
@author.posts = [@first_post, @second_post]
|
||||||
|
|||||||
@ -8,6 +8,7 @@ module ActiveModel
|
|||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@author.posts = []
|
@author.posts = []
|
||||||
|
@author.bio = nil
|
||||||
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
||||||
@post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
|
@post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
|
||||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
|
|||||||
@ -7,6 +7,7 @@ module ActiveModel
|
|||||||
class LinkedTest < Minitest::Test
|
class LinkedTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
|
@bio = Bio.new(id: 1, content: 'AMS Contributor')
|
||||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||||
@first_post.comments = []
|
@first_post.comments = []
|
||||||
@ -14,9 +15,11 @@ module ActiveModel
|
|||||||
@first_post.author = @author
|
@first_post.author = @author
|
||||||
@second_post.author = @author
|
@second_post.author = @author
|
||||||
@author.posts = [@first_post, @second_post]
|
@author.posts = [@first_post, @second_post]
|
||||||
|
@author.bio = @bio
|
||||||
|
@bio.author = @author
|
||||||
|
|
||||||
@serializer = ArraySerializer.new([@first_post, @second_post])
|
@serializer = ArraySerializer.new([@first_post, @second_post])
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'author,comments')
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'author,author.bio,comments')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_include_multiple_posts_and_linked
|
def test_include_multiple_posts_and_linked
|
||||||
@ -31,7 +34,10 @@ module ActiveModel
|
|||||||
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: ['1', '2'], author: "1" } },
|
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: ['1', '2'], author: "1" } },
|
||||||
{ title: "New Post", body: "Body", id: "2", links: { comments: [], :author => "1" } }
|
{ title: "New Post", body: "Body", id: "2", links: { comments: [], :author => "1" } }
|
||||||
], @adapter.serializable_hash[:posts])
|
], @adapter.serializable_hash[:posts])
|
||||||
assert_equal({ :comments => [{ :id => "1", :body => "ZOMG A COMMENT" }, { :id => "2", :body => "ZOMG ANOTHER COMMENT" }], :authors => [{ :id => "1", :name => "Steve K." }] }, @adapter.serializable_hash[:linked])
|
assert_equal({ :comments => [{ :id => "1", :body => "ZOMG A COMMENT" },
|
||||||
|
{ :id => "2", :body => "ZOMG ANOTHER COMMENT" }],
|
||||||
|
:authors => [{ :id => "1", :name => "Steve K." }],
|
||||||
|
:bios=>[{:id=>"1", :content=>"AMS Contributor"}] }, @adapter.serializable_hash[:linked])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
8
test/fixtures/poro.rb
vendored
8
test/fixtures/poro.rb
vendored
@ -38,6 +38,7 @@ end
|
|||||||
Post = Class.new(Model)
|
Post = Class.new(Model)
|
||||||
Comment = Class.new(Model)
|
Comment = Class.new(Model)
|
||||||
Author = Class.new(Model)
|
Author = Class.new(Model)
|
||||||
|
Bio = Class.new(Model)
|
||||||
Blog = Class.new(Model)
|
Blog = Class.new(Model)
|
||||||
|
|
||||||
PostSerializer = Class.new(ActiveModel::Serializer) do
|
PostSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
@ -59,6 +60,13 @@ AuthorSerializer = Class.new(ActiveModel::Serializer) do
|
|||||||
attributes :id, :name
|
attributes :id, :name
|
||||||
|
|
||||||
has_many :posts, embed: :ids
|
has_many :posts, embed: :ids
|
||||||
|
belongs_to :bio
|
||||||
|
end
|
||||||
|
|
||||||
|
BioSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
attributes :id, :content
|
||||||
|
|
||||||
|
belongs_to :author
|
||||||
end
|
end
|
||||||
|
|
||||||
BlogSerializer = Class.new(ActiveModel::Serializer) do
|
BlogSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
|||||||
@ -26,6 +26,7 @@ module ActiveModel
|
|||||||
|
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(name: 'Steve K.')
|
@author = Author.new(name: 'Steve K.')
|
||||||
|
@author.bio = nil
|
||||||
@post = Post.new({ title: 'New Post', body: 'Body' })
|
@post = Post.new({ title: 'New Post', body: 'Body' })
|
||||||
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
||||||
@post.comments = [@comment]
|
@post.comments = [@comment]
|
||||||
@ -39,11 +40,21 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_has_many
|
def test_has_many
|
||||||
assert_equal({posts: {type: :has_many, options: {embed: :ids}}}, @author_serializer.class._associations)
|
assert_equal(
|
||||||
|
{ posts: { type: :has_many, options: { embed: :ids } },
|
||||||
|
bio: { type: :belongs_to, options: {} } },
|
||||||
|
@author_serializer.class._associations
|
||||||
|
)
|
||||||
@author_serializer.each_association do |name, serializer, options|
|
@author_serializer.each_association do |name, serializer, options|
|
||||||
assert_equal(:posts, name)
|
if name == :posts
|
||||||
assert_equal({embed: :ids}, options)
|
assert_equal({embed: :ids}, options)
|
||||||
assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
|
assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
|
||||||
|
elsif name == :bio
|
||||||
|
assert_equal({}, options)
|
||||||
|
assert_nil serializer
|
||||||
|
else
|
||||||
|
flunk "Unknown association: #{name}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user