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

Changeset 7173

Show
Ignore:
Timestamp:
07/09/07 22:07:39 (3 years ago)
Author:
xal
Message:

Support for non heterogeneous arrays when serializing to xml. Unless guessable from array name the type name will be included as attribute

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/test/template/asset_tag_helper_test.rb

    r6729 r7173  
    365365    ActionController::Base.asset_host = nil 
    366366  end 
     367 
     368  def test_asset_host_without_protocol_should_use_request_protocol_even_if_path_present 
     369    ActionController::Base.asset_host = 'a.example.com/files/go/here' 
     370    assert_equal 'gopher://a.example.com/files/go/here/collaboration/hieraki/images/xml.png', image_path('xml.png') 
     371  ensure 
     372    ActionController::Base.asset_host = nil 
     373  end 
    367374end 
  • trunk/activerecord/lib/active_record/xml_serialization.rb

    r7171 r7173  
    212212            else 
    213213              builder.tag!(tag, :type => :array) do 
    214                 records.each { |r| r.to_xml(opts.merge(:root=>r.class.to_s.underscore)) } 
     214                association_name = association.to_s.singularize 
     215                records.each do |record|  
     216                  record.to_xml opts.merge( 
     217                    :root => association_name,  
     218                    :type => (record.class.to_s.underscore == association_name ? nil : record.class.name) 
     219                  ) 
     220                end 
    215221              end 
    216222            end 
     
    247253      if options[:namespace] 
    248254        args << {:xmlns=>options[:namespace]} 
     255      end 
     256       
     257      if options[:type] 
     258        args << {:type=>options[:type]} 
    249259      end 
    250260         
  • trunk/activerecord/test/xml_serialization_test.rb

    r7171 r7173  
    33require 'fixtures/author' 
    44require 'fixtures/tagging' 
     5require 'fixtures/comment' 
    56 
    67class Contact < ActiveRecord::Base 
     
    148149    xml = authors(:david).to_xml :include=>:hello_posts, :indent => 0 
    149150    assert_match %r{<hello-posts type="array">}, xml 
    150     assert_match %r{<post>}, xml 
    151     assert_match %r{<sti-post>}, xml 
     151    assert_match %r{<hello-post type="Post">}, xml 
     152    assert_match %r{<hello-post type="StiPost">}, xml 
    152153  end 
    153154   
     
    172173  end 
    173174   
     175  def test_should_has_many_array_elements_should_include_type_when_different_from_guessed_value 
     176    xml = authors(:david).to_xml :include=>:posts_with_comments, :indent => 2 
     177     
     178    assert Hash.from_xml(xml) 
     179    assert_match %r{^  <posts-with-comments type="array">}, xml 
     180    assert_match %r{^    <posts-with-comment type="Post">}, xml 
     181    assert_match %r{^    <posts-with-comment type="StiPost">}, xml 
     182 
     183    types = Hash.from_xml(xml)['author']['posts_with_comments'].collect {|t| t['type'] } 
     184    assert types.include?('SpecialPost') 
     185    assert types.include?('Post') 
     186    assert types.include?('StiPost') 
     187  end 
     188   
    174189end 
  • trunk/activesupport/lib/active_support/core_ext/hash/conversions.rb

    r7086 r7173  
    168168            def typecast_xml_value(value) 
    169169              case value.class.to_s 
    170                 when "Hash" 
     170                when 'Hash' 
    171171                  if value.has_key?("__content__") 
    172172                    content = translate_xml_entities(value["__content__"]) 
     
    196196                  elsif value['type'] == 'string' && value['nil'] != 'true' 
    197197                    "" 
     198                  # blank or nil parsed values are represented by nil 
     199                  elsif value.blank? || value['nil'] == 'true' 
     200                    nil 
     201                  # If the type is the only element which makes it then  
     202                  # this still makes the value nil 
     203                  elsif value['type'] && value.size == 1 
     204                    nil 
    198205                  else 
    199                     xml_value = (value.blank? || value['type'] || value['nil'] == 'true') ? nil : value.inject({}) do |h,(k,v)| 
     206                    xml_value = value.inject({}) do |h,(k,v)| 
    200207                      h[k] = typecast_xml_value(v) 
    201208                      h 
     
    204211                    # Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with 
    205212                    # how multipart uploaded files from HTML appear 
    206                     if xml_value.is_a?(Hash) && xml_value["file"].is_a?(StringIO) 
    207                       xml_value["file"] 
    208                     else 
    209                       xml_value 
    210                     end 
    211                   end 
    212                 when "Array" 
     213                    xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value 
     214                  end 
     215                when 'Array' 
    213216                  value.map! { |i| typecast_xml_value(i) } 
    214217                  case value.length 
     
    217220                    else value 
    218221                  end 
    219                 when "String" 
     222                when 'String' 
    220223                  value 
    221224                else 
    222                   raise "can't typecast #{value.inspect}" 
     225                  raise "can't typecast #{value.class.name} - #{value.inspect}" 
    223226              end 
    224227            end 
  • trunk/activesupport/test/core_ext/hash_ext_test.rb

    r7172 r7173  
    589589    assert_equal expected_bacon_hash, Hash.from_xml(bacon_xml)["bacon"] 
    590590  end 
     591   
     592  def test_type_trickles_through_when_unknown 
     593    product_xml = <<-EOT 
     594    <product> 
     595      <weight type="double">0.5</weight> 
     596      <image type="ProductImage"><filename>image.gif</filename></image> 
     597       
     598    </product> 
     599    EOT 
     600 
     601    expected_product_hash = { 
     602      :weight => 0.5, 
     603      :image => {'type' => 'ProductImage', 'filename' => 'image.gif' }, 
     604    }.stringify_keys 
     605 
     606    assert_equal expected_product_hash, Hash.from_xml(product_xml)["product"]     
     607  end 
    591608 
    592609  def test_should_use_default_value_for_unknown_key