diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index cd743e4c..e1cb7c6a 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -460,8 +460,7 @@ module ActiveModel # Returns a json representation of the serializable # object including the root. - def as_json(options=nil) - options ||= {} + def as_json(options={}) if root = options.fetch(:root, @options.fetch(:root, _root)) @options[:hash] = hash = {} @options[:unique_values] = {} @@ -477,33 +476,17 @@ module ActiveModel # object without the root. def serializable_hash instrument(:serialize, :serializer => self.class.name) do - node = attributes + @node = attributes instrument :associations do - include_associations!(node) if _embed + include_associations! if _embed end - node + @node end end - def include_associations!(node) - _associations.each do |attr, klass| - 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 + def include_associations! + _associations.each_key do |name| + include! name end end @@ -526,9 +509,17 @@ module ActiveModel @options[:unique_values] ||= {} end - node = options[:node] + node = options[:node] ||= @node value = options[:value] + if options[:include] == nil + if @options.key?(:include) + options[:include] = @options[:include].include?(name) + elsif @options.include?(:exclude) + options[:include] = !@options[:exclude].include?(name) + end + end + association_class = if klass = _associations[name] klass diff --git a/test/serializer_test.rb b/test/serializer_test.rb index 8358178d..fc4ec7dc 100644 --- a/test/serializer_test.rb +++ b/test/serializer_test.rb @@ -37,10 +37,11 @@ class SerializerTest < ActiveModel::TestCase def initialize(attributes) super(attributes) self.comments ||= [] + self.comments_disabled = false self.author = nil end - attr_accessor :comments, :author + attr_accessor :comments, :comments_disabled, :author def active_model_serializer; PostSerializer; end end @@ -89,11 +90,6 @@ class SerializerTest < ActiveModel::TestCase end end - class PostSerializer < ActiveModel::Serializer - attributes :title, :body - has_many :comments, :serializer => CommentSerializer - end - def test_scope_works_correct serializer = ActiveModel::Serializer.new :foo, :scope => :bar assert_equal serializer.scope, :bar @@ -163,6 +159,11 @@ class SerializerTest < ActiveModel::TestCase }, hash) end + class PostSerializer < ActiveModel::Serializer + attributes :title, :body + has_many :comments, :serializer => CommentSerializer + end + def test_has_many user = User.new @@ -184,6 +185,48 @@ class SerializerTest < ActiveModel::TestCase }, post_serializer.as_json) end + class PostWithConditionalCommentsSerializer < ActiveModel::Serializer + root :post + attributes :title, :body + has_many :comments, :serializer => CommentSerializer + + def include_associations! + include! :comments unless object.comments_disabled + end + end + + def test_conditionally_included_associations + user = User.new + + post = Post.new(:title => "New Post", :body => "Body of new post", :email => "tenderlove@tenderlove.com") + comments = [Comment.new(:title => "Comment1"), Comment.new(:title => "Comment2")] + post.comments = comments + + post_serializer = PostWithConditionalCommentsSerializer.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) + end + class Blog < Model attr_accessor :author end