diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index e1cb7c6a..ab60349b 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -328,6 +328,8 @@ module ActiveModel object.read_attribute_for_serialization(attr.to_sym) end end + + define_include_method attr end def associate(klass, attrs) #:nodoc: @@ -341,10 +343,21 @@ module ActiveModel end end + define_include_method attr + self._associations[attr] = klass.refine(attr, options) end end + def define_include_method(name) + method = "include_#{name}?".to_sym + unless method_defined?(method) + define_method method do + true + end + end + end + # Defines an association in the object should be rendered. # # The serializer object should implement the association name @@ -486,10 +499,14 @@ module ActiveModel def include_associations! _associations.each_key do |name| - include! name + include!(name) if include?(name) end end + def include?(name) + send "include_#{name}?".to_sym + end + def include!(name, options={}) # Make sure that if a special options[:hash] was passed in, we generate # a new unique values hash and don't clobber the original. If the hash @@ -569,7 +586,7 @@ module ActiveModel hash = {} _attributes.each do |name,key| - hash[key] = read_attribute_for_serialization(name) + hash[key] = read_attribute_for_serialization(name) if include?(name) end hash diff --git a/test/serializer_test.rb b/test/serializer_test.rb index fc4ec7dc..941d371c 100644 --- a/test/serializer_test.rb +++ b/test/serializer_test.rb @@ -227,6 +227,62 @@ class SerializerTest < ActiveModel::TestCase }, post_serializer.as_json) end + class PostWithMultipleConditionalsSerializer < ActiveModel::Serializer + root :post + attributes :title, :body, :author + has_many :comments, :serializer => CommentSerializer + + def include_comments? + !object.comments_disabled + end + + def include_author? + scope.super_user? + end + end + + def test_conditionally_included_associations_and_attributes + user = User.new + + post = Post.new(:title => "New Post", :body => "Body of new post", :author => 'Sausage King', :email => "tenderlove@tenderlove.com") + comments = [Comment.new(:title => "Comment1"), Comment.new(:title => "Comment2")] + post.comments = comments + + post_serializer = PostWithMultipleConditionalsSerializer.new(post, :scope => user) + + # comments enabled + post.comments_disabled = false + assert_equal({ + :post => { + :title => "New Post", + :body => "Body of new post", + :comments => [ + { :title => "Comment1" }, + { :title => "Comment2" } + ] + } + }, post_serializer.as_json) + + # comments disabled + post.comments_disabled = true + assert_equal({ + :post => { + :title => "New Post", + :body => "Body of new post" + } + }, post_serializer.as_json) + + # superuser - should see author + user.superuser = true + assert_equal({ + :post => { + :title => "New Post", + :body => "Body of new post", + :author => "Sausage King" + } + }, post_serializer.as_json) + end + class Blog < Model attr_accessor :author end