Tested with edge rails and active resource: r7161
Consider the following custom controller methods:
# app/controllers/foos_controller.rb
class FoosController < ApplicationController
def gimme_hash
@res = {'abc'=>'wibble'}
render :xml => @res.to_xml
end
def gimme_array
@res = ['abc']
render :xml => @res.to_xml
end
end
# config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.resources :foos, :collection => {
:gimme_hash => :get,
:gimme_array => :get,
}
# rest as usual
end
# run using:
script/server -p 3001
Now try to access it from an ActiveResource client:
script/console
>> class Foo < ActiveResource::Base; self.site="http://localhost:3001"; end
=> "http://localhost:3001"
>> Foo.get(:gimme_hash)
=> {"abc"=>"wibble"}
>> Foo.get(:gimme_array)
ActiveResource::ServerError: Failed with 500
from /home/candlerb/local/edgetest/vendor/rails/activeresource/lib/active_resource/connection.rb:123:in `handle_response'
from /home/candlerb/local/edgetest/vendor/rails/activeresource/lib/active_resource/connection.rb:104:in `request'
from /home/candlerb/local/edgetest/vendor/rails/activeresource/lib/active_resource/connection.rb:72:in `get'
from /home/candlerb/local/edgetest/vendor/rails/activeresource/lib/active_resource/custom_methods.rb:42:in `get'
from (irb):3
>>
Fundamentally, the problem is that hashes with String keys and values can be serialized with to_xml, but not arrays of Strings:
>> {'abc'=>'wibble'}.to_xml
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n <abc>wibble</abc>\n</hash>\n"
>> [].to_xml
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<nil-classes type=\"array\"/>\n"
>> [Foo.new].to_xml
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<foos type=\"array\">\n <foo>\n </foo>\n</foos>\n"
>> ['abc'].to_xml
RuntimeError: Not all elements respond to to_xml
from /home/candlerb/local/edgetest/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/core_ext/array/conversions.rb:48:in `to_xml'
from (irb):6
I think that being able to serialize an array of Strings (or integers etc) is a reasonable thing to want to do. Perhaps serialize them as <string>....</string>, <integer>...</integer> etc?