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

Ticket #10162: to_xml_more_specific_procs.diff

File to_xml_more_specific_procs.diff, 7.7 kB (added by chuyeow, 8 months ago)

Top-level :procs aren't applied to associations, but :procs on :include work

  • activerecord/test/xml_serialization_test.rb

    old new  
    1111    assert_match %r{^<contact>},  @xml 
    1212    assert_match %r{</contact>$}, @xml 
    1313  end 
    14    
     14 
    1515  def test_should_serialize_default_root_with_namespace 
    1616    @xml = Contact.new.to_xml :namespace=>"http://xml.rubyonrails.org/contact" 
    1717    assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">},  @xml 
    1818    assert_match %r{</contact>$}, @xml 
    1919  end 
    20    
     20 
    2121  def test_should_serialize_custom_root 
    2222    @xml = Contact.new.to_xml :root => 'xml_contact' 
    2323    assert_match %r{^<xml-contact>},  @xml 
    2424    assert_match %r{</xml-contact>$}, @xml 
    2525  end 
    26    
     26 
    2727  def test_should_allow_undasherized_tags 
    2828    @xml = Contact.new.to_xml :root => 'xml_contact', :dasherize => false 
    2929    assert_match %r{^<xml_contact>},  @xml 
     
    4848  def test_should_serialize_string 
    4949    assert_match %r{<name>aaron stack</name>},     @xml 
    5050  end 
    51    
     51 
    5252  def test_should_serialize_integer 
    5353    assert_match %r{<age type="integer">25</age>}, @xml 
    5454  end 
    55    
     55 
    5656  def test_should_serialize_binary 
    5757    assert_match %r{YmluYXJ5ZGF0YQ==\n</avatar>},    @xml 
    5858    assert_match %r{<avatar(.*)(type="binary")},     @xml 
    5959    assert_match %r{<avatar(.*)(encoding="base64")}, @xml 
    6060  end 
    61    
     61 
    6262  def test_should_serialize_datetime 
    6363    assert_match %r{<created-at type=\"datetime\">2006-08-01T00:00:00Z</created-at>}, @xml 
    6464  end 
    65    
     65 
    6666  def test_should_serialize_boolean 
    6767    assert_match %r{<awesome type=\"boolean\">false</awesome>}, @xml 
    6868  end 
    69    
     69 
    7070  def test_should_serialize_yaml 
    7171    assert_match %r{<preferences type=\"yaml\">--- \n:gem: ruby\n</preferences>}, @xml 
    7272  end 
     
    8080  def test_should_serialize_string 
    8181    assert_match %r{<name nil="true"></name>},     @xml 
    8282  end 
    83    
     83 
    8484  def test_should_serialize_integer 
    8585    assert %r{<age (.*)></age>}.match(@xml) 
    8686    attributes = $1 
    8787    assert_match %r{nil="true"}, attributes 
    8888    assert_match %r{type="integer"}, attributes 
    8989  end 
    90    
     90 
    9191  def test_should_serialize_binary 
    9292    assert %r{<avatar (.*)></avatar>}.match(@xml) 
    9393    attributes = $1 
     
    9595    assert_match %r{encoding="base64"}, attributes 
    9696    assert_match %r{nil="true"}, attributes 
    9797  end 
    98    
     98 
    9999  def test_should_serialize_datetime 
    100100    assert %r{<created-at (.*)></created-at>}.match(@xml) 
    101101    attributes = $1 
    102102    assert_match %r{nil="true"}, attributes 
    103103    assert_match %r{type="datetime"}, attributes 
    104104  end 
    105    
     105 
    106106  def test_should_serialize_boolean 
    107107    assert %r{<awesome (.*)></awesome>}.match(@xml) 
    108108    attributes = $1 
    109109    assert_match %r{type="boolean"}, attributes 
    110110    assert_match %r{nil="true"}, attributes 
    111111  end 
    112    
     112 
    113113  def test_should_serialize_yaml 
    114114    assert %r{<preferences(.*)></preferences>}.match(@xml) 
    115115    attributes = $1 
     
    137137    assert_match %r{<hello-post type="Post">}, xml 
    138138    assert_match %r{<hello-post type="StiPost">}, xml 
    139139  end 
    140    
     140 
    141141  def test_methods_are_called_on_object 
    142142    xml = authors(:david).to_xml :methods => :label, :indent => 0 
    143143    assert_match %r{<label>.*</label>}, xml 
    144144  end 
    145    
     145 
    146146  def test_should_not_call_methods_on_associations_that_dont_respond 
    147147    xml = authors(:david).to_xml :include=>:hello_posts, :methods => :label, :indent => 2 
    148148    assert !authors(:david).hello_posts.first.respond_to?(:label) 
    149149    assert_match %r{^  <label>.*</label>}, xml 
    150150    assert_no_match %r{^      <label>}, xml 
    151151  end 
    152    
     152 
     153  def test_procs_are_called_on_object 
     154    proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') } 
     155    xml = authors(:david).to_xml(:procs => [ proc ]) 
     156    assert_match %r{<nationality>Danish</nationality>}, xml 
     157  end 
     158 
     159  def test_top_level_procs_arent_applied_to_associations 
     160    author_proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') } 
     161    xml = authors(:david).to_xml(:procs => [ author_proc ], :include => :posts, :indent => 2) 
     162 
     163    assert_match %r{^  <nationality>Danish</nationality>}, xml 
     164    assert_no_match %r{^ {6}<nationality>Danish</nationality>}, xml 
     165  end 
     166 
     167  def test_procs_on_included_associations_are_called 
     168    posts_proc = Proc.new { |options| options[:builder].tag!('copyright', 'DHH') } 
     169    xml = authors(:david).to_xml( 
     170      :indent => 2, 
     171      :include => { 
     172        :posts => { :procs => [ posts_proc ] } 
     173      } 
     174    ) 
     175 
     176    assert_no_match %r{^  <copyright>DHH</copyright>}, xml 
     177    assert_match %r{^ {6}<copyright>DHH</copyright>}, xml 
     178  end 
     179 
    153180  def test_should_include_empty_has_many_as_empty_array 
    154     authors(:david).posts.delete_all     
     181    authors(:david).posts.delete_all 
    155182    xml = authors(:david).to_xml :include=>:posts, :indent => 2 
    156      
     183 
    157184    assert_equal [], Hash.from_xml(xml)['author']['posts'] 
    158185    assert_match %r{^  <posts type="array"/>}, xml 
    159186  end 
    160    
     187 
    161188  def test_should_has_many_array_elements_should_include_type_when_different_from_guessed_value 
    162189    xml = authors(:david).to_xml :include=>:posts_with_comments, :indent => 2 
    163      
     190 
    164191    assert Hash.from_xml(xml) 
    165192    assert_match %r{^  <posts-with-comments type="array">}, xml 
    166193    assert_match %r{^    <posts-with-comment type="Post">}, xml 
     
    171198    assert types.include?('Post') 
    172199    assert types.include?('StiPost') 
    173200  end 
    174    
     201 
    175202end 
  • activerecord/lib/active_record/serializers/xml_serializer.rb

    old new  
    11module ActiveRecord #:nodoc: 
    22  module Serialization 
    33    # Builds an XML document to represent the model.   Some configuration is 
    4     # available through +options+, however more complicated cases should  
     4    # available through +options+, however more complicated cases should 
    55    # override ActiveRecord's to_xml. 
    66    # 
    7     # By default the generated XML document will include the processing  
     7    # By default the generated XML document will include the processing 
    88    # instruction and all object's attributes.  For example: 
    9     #     
     9    # 
    1010    #   <?xml version="1.0" encoding="UTF-8"?> 
    1111    #   <topic> 
    1212    #     <title>The First Topic</title> 
     
    4242    #     <parent-id></parent-id> 
    4343    #     <last-read type="date">2004-04-15</last-read> 
    4444    #   </topic> 
    45     #  
     45    # 
    4646    # To include first level associations use :include 
    4747    # 
    4848    #   firm.to_xml :include => [ :account, :clients ] 
     
    189189 
    190190    def add_tag(attribute) 
    191191      builder.tag!( 
    192         dasherize? ? attribute.name.dasherize : attribute.name,  
    193         attribute.value.to_s,  
     192        dasherize? ? attribute.name.dasherize : attribute.name, 
     193        attribute.value.to_s, 
    194194        attribute.decorations(!options[:skip_types]) 
    195195      ) 
    196196    end 
     
    204204        else 
    205205          builder.tag!(tag, :type => :array) do 
    206206            association_name = association.to_s.singularize 
    207             records.each do |record|  
     207            records.each do |record| 
    208208              record.to_xml opts.merge( 
    209                 :root => association_name,  
     209                :root => association_name, 
    210210                :type => (record.class.to_s.underscore == association_name ? nil : record.class.name) 
    211211              ) 
    212212            end 
     
    231231 
    232232      builder.tag!(*args) do 
    233233        add_attributes 
     234        procs = options.delete(:procs) 
    234235        add_includes { |association, records, opts| add_associations(association, records, opts) } 
     236        options[:procs] = procs 
    235237        add_procs 
    236238        yield builder if block_given? 
    237239      end