mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Added a :camelize option to ActiveRecord and Hash to_xml serialization and from_xml deserialization
Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
parent
96b815d7e8
commit
aa5cdb0d47
4 changed files with 43 additions and 14 deletions
|
@ -23,11 +23,12 @@ module ActiveRecord #:nodoc:
|
||||||
# </topic>
|
# </topic>
|
||||||
#
|
#
|
||||||
# This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
|
# This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
|
||||||
# <tt>:skip_instruct</tt>, <tt>:skip_types</tt> and <tt>:dasherize</tt>.
|
# <tt>:skip_instruct</tt>, <tt>:skip_types</tt>, <tt>:dasherize</tt> and <tt>:camelize</tt> .
|
||||||
# The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
|
# The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
|
||||||
# +attributes+ method. The default is to dasherize all column names, but you
|
# +attributes+ method. The default is to dasherize all column names, but you
|
||||||
# can disable this setting <tt>:dasherize</tt> to +false+. To not have the
|
# can disable this setting <tt>:dasherize</tt> to +false+. Setting <tt>:camelize</tt>
|
||||||
# column type included in the XML output set <tt>:skip_types</tt> to +true+.
|
# to +true+ will camelize all column names - this also overrides <tt>:dasherize</tt>.
|
||||||
|
# To not have the column type included in the XML output set <tt>:skip_types</tt> to +true+.
|
||||||
#
|
#
|
||||||
# For instance:
|
# For instance:
|
||||||
#
|
#
|
||||||
|
@ -178,13 +179,22 @@ module ActiveRecord #:nodoc:
|
||||||
|
|
||||||
def root
|
def root
|
||||||
root = (options[:root] || @record.class.to_s.underscore).to_s
|
root = (options[:root] || @record.class.to_s.underscore).to_s
|
||||||
dasherize? ? root.dasherize : root
|
reformat_name(root)
|
||||||
end
|
end
|
||||||
|
|
||||||
def dasherize?
|
def dasherize?
|
||||||
!options.has_key?(:dasherize) || options[:dasherize]
|
!options.has_key?(:dasherize) || options[:dasherize]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def camelize?
|
||||||
|
options.has_key?(:camelize) && options[:camelize]
|
||||||
|
end
|
||||||
|
|
||||||
|
def reformat_name(name)
|
||||||
|
name = name.camelize if camelize?
|
||||||
|
dasherize? ? name.dasherize : name
|
||||||
|
end
|
||||||
|
|
||||||
def serializable_attributes
|
def serializable_attributes
|
||||||
serializable_attribute_names.collect { |name| Attribute.new(name, @record) }
|
serializable_attribute_names.collect { |name| Attribute.new(name, @record) }
|
||||||
end
|
end
|
||||||
|
@ -212,7 +222,7 @@ module ActiveRecord #:nodoc:
|
||||||
|
|
||||||
def add_tag(attribute)
|
def add_tag(attribute)
|
||||||
builder.tag!(
|
builder.tag!(
|
||||||
dasherize? ? attribute.name.dasherize : attribute.name,
|
reformat_name(attribute.name),
|
||||||
attribute.value.to_s,
|
attribute.value.to_s,
|
||||||
attribute.decorations(!options[:skip_types])
|
attribute.decorations(!options[:skip_types])
|
||||||
)
|
)
|
||||||
|
@ -220,8 +230,7 @@ module ActiveRecord #:nodoc:
|
||||||
|
|
||||||
def add_associations(association, records, opts)
|
def add_associations(association, records, opts)
|
||||||
if records.is_a?(Enumerable)
|
if records.is_a?(Enumerable)
|
||||||
tag = association.to_s
|
tag = reformat_name(association.to_s)
|
||||||
tag = tag.dasherize if dasherize?
|
|
||||||
if records.empty?
|
if records.empty?
|
||||||
builder.tag!(tag, :type => :array)
|
builder.tag!(tag, :type => :array)
|
||||||
else
|
else
|
||||||
|
|
|
@ -31,6 +31,13 @@ class XmlSerializationTest < ActiveRecord::TestCase
|
||||||
assert_match %r{<created_at}, @xml
|
assert_match %r{<created_at}, @xml
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_should_allow_camelized_tags
|
||||||
|
@xml = Contact.new.to_xml :root => 'xml_contact', :camelize => true
|
||||||
|
assert_match %r{^<XmlContact>}, @xml
|
||||||
|
assert_match %r{</XmlContact>$}, @xml
|
||||||
|
assert_match %r{<CreatedAt}, @xml
|
||||||
|
end
|
||||||
|
|
||||||
def test_should_include_yielded_additions
|
def test_should_include_yielded_additions
|
||||||
@xml = Contact.new.to_xml do |xml|
|
@xml = Contact.new.to_xml do |xml|
|
||||||
xml.creator "David"
|
xml.creator "David"
|
||||||
|
|
|
@ -94,8 +94,7 @@ module ActiveSupport #:nodoc:
|
||||||
options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
|
options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
|
||||||
:root => "hash" })
|
:root => "hash" })
|
||||||
options[:builder].instruct! unless options.delete(:skip_instruct)
|
options[:builder].instruct! unless options.delete(:skip_instruct)
|
||||||
dasherize = !options.has_key?(:dasherize) || options[:dasherize]
|
root = rename_key(options[:root].to_s, options)
|
||||||
root = dasherize ? options[:root].to_s.dasherize : options[:root].to_s
|
|
||||||
|
|
||||||
options[:builder].__send__(:method_missing, root) do
|
options[:builder].__send__(:method_missing, root) do
|
||||||
each do |key, value|
|
each do |key, value|
|
||||||
|
@ -122,7 +121,7 @@ module ActiveSupport #:nodoc:
|
||||||
else
|
else
|
||||||
type_name = XML_TYPE_NAMES[value.class.name]
|
type_name = XML_TYPE_NAMES[value.class.name]
|
||||||
|
|
||||||
key = dasherize ? key.to_s.dasherize : key.to_s
|
key = rename_key(key.to_s, options)
|
||||||
|
|
||||||
attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
|
attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
|
||||||
if value.nil?
|
if value.nil?
|
||||||
|
@ -142,9 +141,16 @@ module ActiveSupport #:nodoc:
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def rename_key(key, options = {})
|
||||||
|
camelize = options.has_key?(:camelize) && options[:camelize]
|
||||||
|
dasherize = !options.has_key?(:dasherize) || options[:dasherize]
|
||||||
|
key = key.camelize if camelize
|
||||||
|
dasherize ? key.dasherize : key
|
||||||
|
end
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def from_xml(xml)
|
def from_xml(xml)
|
||||||
typecast_xml_value(undasherize_keys(XmlMini.parse(xml)))
|
typecast_xml_value(unrename_keys(XmlMini.parse(xml)))
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -210,15 +216,15 @@ module ActiveSupport #:nodoc:
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def undasherize_keys(params)
|
def unrename_keys(params)
|
||||||
case params.class.to_s
|
case params.class.to_s
|
||||||
when "Hash"
|
when "Hash"
|
||||||
params.inject({}) do |h,(k,v)|
|
params.inject({}) do |h,(k,v)|
|
||||||
h[k.to_s.tr("-", "_")] = undasherize_keys(v)
|
h[k.to_s.underscore.tr("-", "_")] = unrename_keys(v)
|
||||||
h
|
h
|
||||||
end
|
end
|
||||||
when "Array"
|
when "Array"
|
||||||
params.map { |v| undasherize_keys(v) }
|
params.map { |v| unrename_keys(v) }
|
||||||
else
|
else
|
||||||
params
|
params
|
||||||
end
|
end
|
||||||
|
|
|
@ -403,6 +403,13 @@ class HashToXmlTest < Test::Unit::TestCase
|
||||||
assert xml.include?(%(<name>David</name>))
|
assert xml.include?(%(<name>David</name>))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_one_level_camelize_true
|
||||||
|
xml = { :name => "David", :street_name => "Paulina" }.to_xml(@xml_options.merge(:camelize => true))
|
||||||
|
assert_equal "<Person>", xml.first(8)
|
||||||
|
assert xml.include?(%(<StreetName>Paulina</StreetName>))
|
||||||
|
assert xml.include?(%(<Name>David</Name>))
|
||||||
|
end
|
||||||
|
|
||||||
def test_one_level_with_types
|
def test_one_level_with_types
|
||||||
xml = { :name => "David", :street => "Paulina", :age => 26, :age_in_millis => 820497600000, :moved_on => Date.new(2005, 11, 15), :resident => :yes }.to_xml(@xml_options)
|
xml = { :name => "David", :street => "Paulina", :age => 26, :age_in_millis => 820497600000, :moved_on => Date.new(2005, 11, 15), :resident => :yes }.to_xml(@xml_options)
|
||||||
assert_equal "<person>", xml.first(8)
|
assert_equal "<person>", xml.first(8)
|
||||||
|
|
Loading…
Reference in a new issue