Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #9294: to_xml_attribute_names_conflict.diff

File to_xml_attribute_names_conflict.diff, 5.5 kB (added by juanjo.bazan, 11 months ago)

code to solve the problem and tests included

  • activesupport/lib/active_support/vendor/builder/xmlbase.rb

    old new  
    2929    # is the tag name, the arguements are the same as the tags 
    3030    # implemented via <tt>method_missing</tt>. 
    3131    def tag!(sym, *args, &block) 
    32       self.__send__(sym, *args, &block) 
     32      #A prefix is added (_railsprefix_) to the name of the method  
     33      # to avoid conflicts with internal methods(like 'open', 'notify' or 'system') 
     34      #The prefix is eliminated in method_missing. 
     35      self.__send__("_rails_prefix_#{sym}", *args, &block)  
    3336    end 
    3437 
    3538    # Create XML markup based on the name of the method.  This method 
    3639    # is never invoked directly, but is called for each markup method 
    3740    # in the markup block. 
    3841    def method_missing(sym, *args, &block) 
     42      #remove the prefix added in tag! method 
     43      sym=sym.to_s 
     44      sym.sub!("_rails_prefix_","") 
     45 
    3946      text = nil 
    4047      attrs = nil 
    4148      sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol) 
    4249      args.each do |arg| 
    43         case arg 
    44         when Hash 
    45           attrs ||= {} 
    46           attrs.merge!(arg) 
    47         else 
    48           text ||= '' 
    49           text << arg.to_s 
    50         end 
     50        case arg 
     51          when Hash 
     52            attrs ||= {} 
     53            attrs.merge!(arg) 
     54 
     55          else 
     56            text ||= '' 
     57            text << arg.to_s 
     58        end 
    5159      end 
    5260      if block 
    53        unless text.nil? 
    54          raise ArgumentError, "XmlMarkup cannot mix a text argument with a block" 
    55        end 
    56        _capture_outer_self(block) unless defined?(@self) && !@self.nil? 
    57        _indent 
    58        _start_tag(sym, attrs) 
    59        _newline 
    60        _nested_structures(block) 
    61        _indent 
    62        _end_tag(sym) 
    63        _newline 
     61        unless text.nil? 
     62          raise ArgumentError, "XmlMarkup cannot mix a text argument with a block" 
     63        end 
     64        _capture_outer_self(block) unless defined?(@self) && !@self.nil? 
     65        _indent 
     66        _start_tag(sym, attrs) 
     67        _newline 
     68        _nested_structures(block) 
     69        _indent 
     70        _end_tag(sym) 
     71        _newline 
    6472      elsif text.nil? 
    65        _indent 
    66        _start_tag(sym, attrs, true) 
    67        _newline 
     73        _indent 
     74        _start_tag(sym, attrs, true) 
     75        _newline 
    6876      else 
    69        _indent 
    70        _start_tag(sym, attrs) 
    71        text! text 
    72        _end_tag(sym) 
    73        _newline 
     77        _indent 
     78        _start_tag(sym, attrs) 
     79        text! text 
     80        _end_tag(sym) 
     81        _newline 
    7482      end 
    7583      @target 
    7684    end 
  • activerecord/test/xml_serialization_test.rb

    old new  
    1717  column :created_at,  :datetime 
    1818  column :awesome,     :boolean 
    1919  column :preferences, :string 
     20  column :open,        :string 
     21  column :notify,      :boolean 
    2022   
    2123  serialize :preferences 
    2224end 
     
    6668 
    6769    assert_match %r{<creator>David</creator>}, @xml 
    6870  end 
     71   
     72  def test_attribute_filtering_should_work_with_special_names 
     73    @xml = Contact.new.to_xml :only => [:notify, :name] 
     74    assert_match %r{<notify},          @xml 
     75    assert_no_match %r{<open}, @xml 
     76     
     77    @xml = Contact.new.to_xml :except => [:notify] 
     78    assert_no_match %r{<notify},    @xml 
     79    assert_match %r{<open},     @xml 
     80  end 
     81   
    6982end 
    7083 
    7184class DefaultXmlSerializationTest < Test::Unit::TestCase 
    7285  def setup 
    73     @xml = Contact.new(:name => 'aaron stack', :age => 25, :avatar => 'binarydata', :created_at => Time.utc(2006, 8, 1), :awesome => false, :preferences => { :gem => 'ruby' }).to_xml 
     86    @xml = Contact.new(:name => 'aaron stack', :age => 25, :avatar => 'binarydata', :created_at => Time.utc(2006, 8, 1), :awesome => false, :preferences => { :gem => 'ruby' }, :open=>"24/7", :notify=>true).to_xml 
    7487  end 
    7588 
    7689  def test_should_serialize_string 
     
    98111  def test_should_serialize_yaml 
    99112    assert_match %r{<preferences type=\"yaml\">--- \n:gem: ruby\n</preferences>}, @xml 
    100113  end 
     114   
     115  def test_should_accept_special_named_columns 
     116    assert_match %r{<open>.*</open>}, @xml 
     117    assert_match %r{<notify type=\"boolean\">.*</notify>}, @xml 
     118  end 
    101119end 
    102120 
    103121class NilXmlSerializationTest < Test::Unit::TestCase 
     
    186204    assert types.include?('StiPost') 
    187205  end 
    188206   
     207  def test_calling_special_names 
     208    @xml = authors(:david).to_xml do |xml| 
     209      xml.open "9:00 to 17:00" 
     210      xml.tag!("notify",[true]) 
     211    end 
     212 
     213    assert_match %r{<open>9:00 to 17:00</open>}, @xml 
     214    assert_match %r{<notify>true</notify>}, @xml 
     215  end 
     216   
    189217end 
  • activerecord/lib/active_record/xml_serialization.rb

    old new  
    320320        end 
    321321     
    322322        def compute_value 
    323           value = @record.send(name) 
     323          value = @record.is_a?(ActiveRecord::Base) && @record.class.serialized_attributes.has_key?(name) ? @record.send(name+"_before_type_cast") : @record.send(name) 
    324324         
    325325          if formatter = Hash::XML_FORMATTING[type.to_s] 
    326326            value ? formatter.call(value) : nil