Use respond_to?(:to_ary) rather than is_a?(Enumerable) to detect collection-thing.

This commit is contained in:
Jon Leighton 2012-05-11 17:17:29 +01:00
parent b892b4c08f
commit a8637cf493
4 changed files with 40 additions and 3 deletions

@ -87,8 +87,8 @@ def serializable_hash(options = nil)
Array(options[:methods]).each { |m| hash[m.to_s] = send(m) if respond_to?(m) }
serializable_add_includes(options) do |association, records, opts|
hash[association.to_s] = if records.is_a?(Enumerable)
records.map { |a| a.serializable_hash(opts) }
hash[association.to_s] = if records.respond_to?(:to_ary)
records.to_ary.map { |a| a.serializable_hash(opts) }
else
records.serializable_hash(opts)
end

@ -115,7 +115,9 @@ def add_associations(association, records, opts)
merged_options = opts.merge(options.slice(:builder, :indent))
merged_options[:skip_instruct] = true
if records.is_a?(Enumerable)
if records.respond_to?(:to_ary)
records = records.to_ary
tag = ActiveSupport::XmlMini.rename_key(association.to_s, options)
type = options[:skip_types] ? { } : {:type => "array"}
association_name = association.to_s.singularize

@ -105,6 +105,24 @@ def test_include_option_with_empty_association
assert_equal expected, @user.serializable_hash(:include => :friends)
end
class FriendList
def initialize(friends)
@friends = friends
end
def to_ary
@friends
end
end
def test_include_option_with_ary
@user.friends = FriendList.new(@user.friends)
expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David",
"friends"=>[{"name"=>'Joe', "email"=>'joe@example.com', "gender"=>'male'},
{"name"=>'Sue', "email"=>'sue@example.com', "gender"=>'female'}]}
assert_equal expected, @user.serializable_hash(:include => :friends)
end
def test_multiple_includes
expected = {"email"=>"david@example.com", "gender"=>"male", "name"=>"David",
"address"=>{"street"=>"123 Lane", "city"=>"Springfield", "state"=>"CA", "zip"=>11111},

@ -188,6 +188,23 @@ def setup
assert_match %r{<friend type="Contact">}, xml
end
class FriendList
def initialize(friends)
@friends = friends
end
def to_ary
@friends
end
end
test "include option with ary" do
@contact.friends = FriendList.new(@contact.friends)
xml = @contact.to_xml :include => :friends, :indent => 0
assert_match %r{<friends type="array">}, xml
assert_match %r{<friend type="Contact">}, xml
end
test "multiple includes" do
xml = @contact.to_xml :indent => 0, :skip_instruct => true, :include => [ :address, :friends ]
assert xml.include?(@contact.address.to_xml(:indent => 0, :skip_instruct => true))