[Rails] is it possible to make to_xml use underscore instead of dash?

Peter Armstrong peterarmstrong at gmail.com
Mon Jul 31 08:34:20 GMT 2006


Thanks!

(By the way, my wife thinks your email address is great :-)

On 7/31/06, snacktime <snacktime at gmail.com> wrote:
> On 7/31/06, Peter Armstrong <peterarmstrong at gmail.com> wrote:
> > Hi all,
> >
> > I am getting ActiveRecord to produce XML with
> >
> >       render :xml => @user.to_xml
> >
> > However, on the client end it is a bit annoying for me to deal with
> > attributes like first-name.  I would much rather have first_name.
> >
> > Is there any way for me to turn off the behavior of converting _ to -?
> >  This seems to be done by a call to dasherize inside the to_xml of
> > ActiveSupport::CoreExtensions::Array::Conversions, so I'm a bit out of
> > my depth...
>
> I just ran into that same issue, and no there isn't an option to not
> dasherize..  I just subclassed the Conversions module for both hashes
> and arrays and created a to_xml_nodash.  All you have to do is get rid
> of the calls to dasherize, but you need to do it for array and hash,
> as hash calls array.  I was just hacking on this tonight, following is
> the code I put at the top of application.rb.  Probably a better idea
> to stick it in the lib directory and require it, but haven't done that
> yet since I was just hacking on it this evening.
>
> module ActiveSupport #:nodoc:
>   module CoreExtensions #:nodoc:
>     module Hash #:nodoc:
>       module Conversions
>         def to_xml_nodash(options = {})
>           options[:indent] ||= 0
>           options.reverse_merge!({ :builder =>
> Builder::XmlMarkup.new(:indent => options[:indent]), :root => "hash"
> })
>           options[:builder].instruct! unless options.delete(:skip_instruct)
>
>           options[:builder].__send__(options[:root].to_s) do
>             each do |key, value|
>               case value
>                 when ::Hash
>                   value.to_xml_nodash(options.merge({ :root => key,
> :skip_instruct => true }))
>                 when ::Array
>                   value.to_xml_nodash(options.merge({ :root => key,
> :children => key.to_s.singularize, :skip_instruct => true}))
>                 else
>                   type_name = XML_TYPE_NAMES[value.class.to_s]
>
>                   options[:builder].tag!(key.to_s,
>                     XML_FORMATTING[type_name] ?
> XML_FORMATTING[type_name].call(value) : value,
>                     options[:skip_types] || value.nil? ||
> type_name.nil? ? { } : { :type => type_name }
>                   )
>               end
>             end
>           end
>         end
>       end
>     end
>   end
> end
> module ActiveSupport #:nodoc:
>   module CoreExtensions #:nodoc:
>     module Array #:nodoc:
>       module Conversions
>         def to_xml_nodash(options = {})
>           raise "Not all elements respond to to_xml" unless all? { |e|
> e.respond_to? :to_xml_nodash }
>
>           options[:root]     ||= all? { |e| e.is_a?(first.class) &&
> first.class.to_s != "Hash" } ? first.class.to_s.underscore.pluralize :
> "re
> cords"
>           options[:children] ||= options[:root].singularize
>           options[:indent]   ||= 2
>           options[:builder]  ||= Builder::XmlMarkup.new(:indent =>
> options[:indent])
>
>           root     = options.delete(:root)
>           children = options.delete(:children)
>
>           options[:builder].instruct! unless options.delete(:skip_instruct)
>           options[:builder].tag!(root.to_s) { each { |e|
> e.to_xml_nodash(options.merge({ :skip_instruct => true, :root =>
> children })) } }
>         end
>       end
>     end
>   end
> end
> _______________________________________________
> Rails mailing list
> Rails at lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>


More information about the Rails mailing list