Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix infinite recursion #722

Merged
merged 1 commit into from
Nov 10, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions lib/active_model/serializer/adapter/json_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,9 @@ def add_linked(resource, serializer, parent = nil)
@top[:linked][plural_name].push attrs unless @top[:linked][plural_name].include? attrs
end

unless serializer.respond_to?(:each)
serializer.each_association do |name, association, opts|
add_linked(name, association, resource) if association
end
end
serializer.each_association do |name, association, opts|
add_linked(name, association, resource_path) if association
end if include_nested_assoc? resource_path
end

private
Expand All @@ -98,8 +96,20 @@ def attributes_for_serializer(serializer, options)
attributes
end

def include_assoc? assoc
@options[:include] && @options[:include].split(',').include?(assoc.to_s)
def include_assoc?(assoc)
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
Expand Down
2 changes: 2 additions & 0 deletions test/action_controller/json_api_linked_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ class MyController < ActionController::Base
def setup_post
@author = Author.new(id: 1, name: 'Steve K.')
@author.posts = []
@author.bio = nil
@author2 = Author.new(id: 2, name: 'Anonymous')
@author2.posts = []
@author2.bio = nil
@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')
Expand Down
1 change: 1 addition & 0 deletions test/adapter/json_api/belongs_to_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class JsonApi
class BelongsToTest < Minitest::Test
def setup
@author = Author.new(id: 1, name: 'Steve K.')
@author.bio = nil
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
Expand Down
1 change: 1 addition & 0 deletions test/adapter/json_api/collection_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class JsonApi
class CollectionTest < Minitest::Test
def setup
@author = Author.new(id: 1, name: 'Steve K.')
@author.bio = nil
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
@first_post.comments = []
Expand Down
1 change: 1 addition & 0 deletions test/adapter/json_api/has_many_embed_ids_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class JsonApi
class HasManyEmbedIdsTest < Minitest::Test
def setup
@author = Author.new(name: 'Steve K.')
@author.bio = 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]
Expand Down
1 change: 1 addition & 0 deletions test/adapter/json_api/has_many_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class HasManyTest < Minitest::Test
def setup
@author = Author.new(id: 1, name: 'Steve K.')
@author.posts = []
@author.bio = nil
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
@post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
Expand Down
10 changes: 8 additions & 2 deletions test/adapter/json_api/linked_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ class JsonApi
class LinkedTest < Minitest::Test
def setup
@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!!')
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
@first_post.comments = []
@second_post.comments = []
@first_post.author = @author
@second_post.author = @author
@author.posts = [@first_post, @second_post]
@author.bio = @bio
@bio.author = @author

@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

def test_include_multiple_posts_and_linked
Expand All @@ -31,7 +34,10 @@ def test_include_multiple_posts_and_linked
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: ['1', '2'], author: "1" } },
{ title: "New Post", body: "Body", id: "2", links: { comments: [], :author => "1" } }
], @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
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/poro.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class ProfileSerializer < ActiveModel::Serializer
Post = Class.new(Model)
Comment = Class.new(Model)
Author = Class.new(Model)
Bio = Class.new(Model)
Blog = Class.new(Model)

PostSerializer = Class.new(ActiveModel::Serializer) do
Expand All @@ -59,6 +60,13 @@ class ProfileSerializer < ActiveModel::Serializer
attributes :id, :name

has_many :posts, embed: :ids
belongs_to :bio
end

BioSerializer = Class.new(ActiveModel::Serializer) do
attributes :id, :content

belongs_to :author
end

BlogSerializer = Class.new(ActiveModel::Serializer) do
Expand Down
19 changes: 15 additions & 4 deletions test/serializers/associations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def method_missing(meth, *args)

def setup
@author = Author.new(name: 'Steve K.')
@author.bio = nil
@post = Post.new({ title: 'New Post', body: 'Body' })
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
@post.comments = [@comment]
Expand All @@ -39,11 +40,21 @@ def setup
end

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|
assert_equal(:posts, name)
assert_equal({embed: :ids}, options)
assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
if name == :posts
assert_equal({embed: :ids}, options)
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

Expand Down