From 51bef9d8fb0b4da7a104425ab8545e9331387743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 18 Sep 2011 09:09:01 -0700 Subject: to_xml should also rely on serializable hash. --- activemodel/lib/active_model/serializers/xml.rb | 46 +++++++--------------- .../cases/serializers/xml_serialization_test.rb | 17 ++++++++ .../active_record/serializers/xml_serializer.rb | 2 +- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb index 64dda3bcee..d61d9d7119 100644 --- a/activemodel/lib/active_model/serializers/xml.rb +++ b/activemodel/lib/active_model/serializers/xml.rb @@ -15,10 +15,10 @@ module ActiveModel class Attribute #:nodoc: attr_reader :name, :value, :type - def initialize(name, serializable, raw_value=nil) + def initialize(name, serializable, value) @name, @serializable = name, serializable - raw_value = raw_value.in_time_zone if raw_value.respond_to?(:in_time_zone) - @value = raw_value || @serializable.send(name) + value = value.in_time_zone if value.respond_to?(:in_time_zone) + @value = value @type = compute_type end @@ -49,40 +49,24 @@ module ActiveModel def initialize(serializable, options = nil) @serializable = serializable @options = options ? options.dup : {} - - @options[:only] = Array.wrap(@options[:only]).map { |n| n.to_s } - @options[:except] = Array.wrap(@options[:except]).map { |n| n.to_s } end - # To replicate the behavior in ActiveRecord#attributes, :except - # takes precedence over :only. If :only is not set - # for a N level model but is set for the N+1 level models, - # then because :except is set to a default value, the second - # level model can have both :except and :only set. So if - # :only is set, always delete :except. - def attributes_hash - attributes = @serializable.attributes - if options[:only].any? - attributes.slice(*options[:only]) - elsif options[:except].any? - attributes.except(*options[:except]) - else - attributes - end + def serializable_hash + @serializable.serializable_hash(@options.except(:include)) end - def serializable_attributes - attributes_hash.map do |name, value| - self.class::Attribute.new(name, @serializable, value) + def serializable_collection + methods = Array.wrap(options[:methods]).map(&:to_s) + serializable_hash.map do |name, value| + name = name.to_s + if methods.include?(name) + self.class::MethodAttribute.new(name, @serializable, value) + else + self.class::Attribute.new(name, @serializable, value) + end end end - def serializable_methods - Array.wrap(options[:methods]).map do |name| - self.class::MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s) - end.compact - end - def serialize require 'builder' unless defined? ::Builder @@ -114,7 +98,7 @@ module ActiveModel end def add_attributes_and_methods - (serializable_attributes + serializable_methods).each do |attribute| + serializable_collection.each do |attribute| key = ActiveSupport::XmlMini.rename_key(attribute.name, options) ActiveSupport::XmlMini.to_tag(key, attribute.value, options.merge(attribute.decorations)) diff --git a/activemodel/test/cases/serializers/xml_serialization_test.rb b/activemodel/test/cases/serializers/xml_serialization_test.rb index a38ef8e223..fc73d9dcd8 100644 --- a/activemodel/test/cases/serializers/xml_serialization_test.rb +++ b/activemodel/test/cases/serializers/xml_serialization_test.rb @@ -33,6 +33,12 @@ class Address end end +class SerializableContact < Contact + def serializable_hash(options={}) + super(options.merge(:only => [:name, :age])) + end +end + class XmlSerializationTest < ActiveModel::TestCase def setup @contact = Contact.new @@ -96,6 +102,17 @@ class XmlSerializationTest < ActiveModel::TestCase assert_match %r{aaron stack}, @xml + assert_match %r{25}, @xml + assert_no_match %r{}, @xml + end + test "should allow skipped types" do @xml = @contact.to_xml :skip_types => true assert_match %r{25}, @xml diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb index cbfa1ad609..0e7f57aa43 100644 --- a/activerecord/lib/active_record/serializers/xml_serializer.rb +++ b/activerecord/lib/active_record/serializers/xml_serializer.rb @@ -179,7 +179,7 @@ module ActiveRecord #:nodoc: class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc: def initialize(*args) super - options[:except] |= Array.wrap(@serializable.class.inheritance_column) + options[:except] = Array.wrap(options[:except]) | Array.wrap(@serializable.class.inheritance_column) end class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc: -- cgit v1.2.3