From 4ad9c64e46dbd7766726d0a013934b30ba4fdbc8 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Wed, 11 Jan 2012 20:56:36 -0700 Subject: [PATCH] Allow serializers to receive instructions to explicitly include or exclude specific lists of associations. --- lib/active_model/serializer.rb | 18 +++++++- test/association_test.rb | 84 ++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index f601a409..1ba94bec 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -372,7 +372,23 @@ module ActiveModel def include_associations!(node) _associations.each do |attr, klass| - include! attr, :node => node + opts = { :node => node } + + if options.include?(:include) || options.include?(:exclude) + opts[:include] = included_association?(attr) + end + + include! attr, opts + end + end + + def included_association?(name) + if options.key?(:include) + options[:include].include?(name) + elsif options.key?(:exclude) + !options[:exclude].include?(name) + else + true end end diff --git a/test/association_test.rb b/test/association_test.rb index dcb8d53e..b8687b33 100644 --- a/test/association_test.rb +++ b/test/association_test.rb @@ -305,4 +305,88 @@ class AssociationTest < ActiveModel::TestCase }, @root_hash) end end + + class InclusionTest < AssociationTest + def setup + super + + comment_serializer_class = @comment_serializer_class + + @post_serializer_class.class_eval do + root :post + embed :ids, :include => true + has_many :comments, :serializer => comment_serializer_class + end + end + + def test_when_it_is_included + post_serializer = @post_serializer_class.new( + @post, nil, :include => [:comments] + ) + + json = post_serializer.as_json + + assert_equal({ + :post => { + :title => "New Post", + :body => "Body", + :comments => [ 1 ] + }, + :comments => [ + { :id => 1, :body => "ZOMG A COMMENT" } + ] + }, json) + end + + def test_when_it_is_not_included + post_serializer = @post_serializer_class.new( + @post, nil, :include => [] + ) + + json = post_serializer.as_json + + assert_equal({ + :post => { + :title => "New Post", + :body => "Body", + :comments => [ 1 ] + } + }, json) + end + + def test_when_it_is_excluded + post_serializer = @post_serializer_class.new( + @post, nil, :exclude => [:comments] + ) + + json = post_serializer.as_json + + assert_equal({ + :post => { + :title => "New Post", + :body => "Body", + :comments => [ 1 ] + } + }, json) + end + + def test_when_it_is_not_excluded + post_serializer = @post_serializer_class.new( + @post, nil, :exclude => [] + ) + + json = post_serializer.as_json + + assert_equal({ + :post => { + :title => "New Post", + :body => "Body", + :comments => [ 1 ] + }, + :comments => [ + { :id => 1, :body => "ZOMG A COMMENT" } + ] + }, json) + end + end end