define include_XXX? methods, which can be overridden to conditionally include attributes and associations

This commit is contained in:
Dan Gebhardt 2012-08-29 09:26:41 -04:00
parent 68dc57eb73
commit 42221a6140
2 changed files with 75 additions and 2 deletions

View File

@ -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

View File

@ -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