ActiveRecord::Base#to_xml woes

Written on 11:10:00 PM by S. Potter

For us Railies that use namespaced models inside Ruby modules and are relying on ActiveRecord::Base#to_xml, do not fret any longer. To reproduce the problem you just need to do something like: users = Legacy::User.find(:all) #=> [] users.to_xml #=> <?xml version=\"1.0\" encoding=\"UTF-8\"?><legacy/users></legacy/users> The XML produced by #to_xml is NOT valid XML for this case. It's been a small thorn in my side for a week or so now and I've been living with it by adding the following to a file that is eventually/implicitly required by environment.rb:

# Patch for Rails #8305 that I submitted on 2007-05-09
# We'll need to keep an eye out upon next Rails Gem upgrade whether or not this 
# fix has been applied to remove this or not.
require 'active_record'
require 'active_support'

class ActiveRecord::Base
  alias :old_to_xml :to_xml
  def to_xml(options = {}, &block)
    options[:root] ||= self.class.name.tableize.singularize.gsub(/\//, ':') # for models that are namespaced in Ruby module
    old_to_xml(options, &block)
  end
end

module ContainerPatchMixin
  def self.included(base)
    base.class_eval %{
      alias :old_to_xml :to_xml
    }
    base.send(:include, InstanceMethods)
  end
  
  module InstanceMethods
    def to_xml(options = {})
      contained_class = self.first.class.name
      options[:root] ||= contained_class.tableize.gsub(/\//, ':') # for models that are namespaced in Ruby module
      options[:children] ||= contained_class.tableize.singularize.gsub(/\//, ':') # for models that are namespaced in Ruby module
      old_to_xml(options)
    end
  end
end

class Array
  include ContainerPatchMixin
end
Now what is produced is something more along the lines of: <?xml version=\"1.0\" encoding=\"UTF-8\"?><legacy:users></legacy:users> Which is valid XML. Today I finally reported this edge case defect on dev.rubyonrails.org (#8305) as I hadn't seen anyone else report it yet. Thankfully this is Ruby and this is all possible while the Rails Core team determine if my not so elegant fix is worthy to be in the next Rails version or not.

If you enjoyed this post Subscribe to our feed

No Comment

Post a Comment