Skip to content
This repository
Browse code

Patch to ActiveModel's (and ActiveRecord, by association) XML seriali…

…zation: If two parameters are present in Procs supplied to to_xml's :procs option, the model being serialized will be passed as the second argument [#2373 state:resolved]

Signed-off-by: Joshua Peek <josh@joshpeek.com>
  • Loading branch information...
commit c39151a84768397d3bb025c6e8f877eac59ebbf9 1 parent 9d7aae7
John Maxwell authored July 22, 2009 josh committed July 22, 2009
6  activemodel/lib/active_model/serializers/xml.rb
@@ -152,7 +152,11 @@ def add_attributes
152 152
           def add_procs
153 153
             if procs = options.delete(:procs)
154 154
               [ *procs ].each do |proc|
155  
-                proc.call(options)
  155
+                if proc.arity > 1
  156
+                  proc.call(options, @serializable)
  157
+                else
  158
+                  proc.call(options)
  159
+                end
156 160
               end
157 161
             end
158 162
           end
12  activemodel/test/cases/serializeration/xml_serialization_test.rb
@@ -82,4 +82,16 @@ def setup
82 82
   test "should serialize yaml" do
83 83
     assert_match %r{<preferences type=\"yaml\">--- \n:gem: ruby\n</preferences>}, @contact.to_xml
84 84
   end
  85
+
  86
+  test "should call proc on object" do
  87
+    proc = Proc.new { |options| options[:builder].tag!('nationality', 'unknown') }
  88
+    xml = @contact.to_xml(:procs => [ proc ])
  89
+    assert_match %r{<nationality>unknown</nationality>}, xml
  90
+  end
  91
+
  92
+  test 'should supply serializable to second proc argument' do
  93
+    proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
  94
+    xml = @contact.to_xml(:procs => [ proc ])
  95
+    assert_match %r{<name-reverse>kcats noraa</name-reverse>}, xml
  96
+  end
85 97
 end
15  activerecord/lib/active_record/serializers/xml_serializer.rb
@@ -71,6 +71,21 @@ module Serialization
71 71
     #     </account>
72 72
     #   </firm>
73 73
     #
  74
+    # Additionally, the record being serialized will be passed to a Proc's second
  75
+    # parameter.  This allows for ad hoc additions to the resultant document that
  76
+    # incorporate the context of the record being serialized. And by leveraging the
  77
+    # closure created by a Proc, to_xml can be used to add elements that normally fall
  78
+    # outside of the scope of the model -- for example, generating and appending URLs
  79
+    # associated with models.
  80
+    # 
  81
+    #   proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
  82
+    #   firm.to_xml :procs => [ proc ]
  83
+    #
  84
+    #   <firm>
  85
+    #     # ... normal attributes as shown above ...
  86
+    #     <name-reverse>slangis73</name-reverse>
  87
+    #   </firm>
  88
+    #
74 89
     # To include deeper levels of associations pass a hash like this:
75 90
     #
76 91
     #   firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
6  activerecord/test/cases/xml_serialization_test.rb
@@ -174,6 +174,12 @@ def test_procs_are_called_on_object
174 174
     assert_match %r{<nationality>Danish</nationality>}, xml
175 175
   end
176 176
 
  177
+  def test_dual_arity_procs_are_called_on_object
  178
+    proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
  179
+    xml = authors(:david).to_xml(:procs => [ proc ])
  180
+    assert_match %r{<name-reverse>divaD</name-reverse>}, xml
  181
+  end
  182
+
177 183
   def test_top_level_procs_arent_applied_to_associations
178 184
     author_proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') }
179 185
     xml = authors(:david).to_xml(:procs => [ author_proc ], :include => :posts, :indent => 2)

0 notes on commit c39151a

Please sign in to comment.
Something went wrong with that request. Please try again.