Skip to content

Commit

Permalink
Patch to ActiveModel's (and ActiveRecord, by association) XML seriali…
Browse files Browse the repository at this point in the history
…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
johnmaxwell authored and josh committed Jul 23, 2009
1 parent 9d7aae7 commit c39151a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 1 deletion.
6 changes: 5 additions & 1 deletion activemodel/lib/active_model/serializers/xml.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -152,7 +152,11 @@ def add_attributes
def add_procs def add_procs
if procs = options.delete(:procs) if procs = options.delete(:procs)
[ *procs ].each do |proc| [ *procs ].each do |proc|
proc.call(options) if proc.arity > 1
proc.call(options, @serializable)
else
proc.call(options)
end
end end
end end
end end
Expand Down
12 changes: 12 additions & 0 deletions activemodel/test/cases/serializeration/xml_serialization_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -82,4 +82,16 @@ def setup
test "should serialize yaml" do test "should serialize yaml" do
assert_match %r{<preferences type=\"yaml\">--- \n:gem: ruby\n</preferences>}, @contact.to_xml assert_match %r{<preferences type=\"yaml\">--- \n:gem: ruby\n</preferences>}, @contact.to_xml
end end

test "should call proc on object" do
proc = Proc.new { |options| options[:builder].tag!('nationality', 'unknown') }
xml = @contact.to_xml(:procs => [ proc ])
assert_match %r{<nationality>unknown</nationality>}, xml
end

test 'should supply serializable to second proc argument' do
proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
xml = @contact.to_xml(:procs => [ proc ])
assert_match %r{<name-reverse>kcats noraa</name-reverse>}, xml
end
end end
15 changes: 15 additions & 0 deletions activerecord/lib/active_record/serializers/xml_serializer.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -71,6 +71,21 @@ module Serialization
# </account> # </account>
# </firm> # </firm>
# #
# Additionally, the record being serialized will be passed to a Proc's second
# parameter. This allows for ad hoc additions to the resultant document that
# incorporate the context of the record being serialized. And by leveraging the
# closure created by a Proc, to_xml can be used to add elements that normally fall
# outside of the scope of the model -- for example, generating and appending URLs
# associated with models.
#
# proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
# firm.to_xml :procs => [ proc ]
#
# <firm>
# # ... normal attributes as shown above ...
# <name-reverse>slangis73</name-reverse>
# </firm>
#
# To include deeper levels of associations pass a hash like this: # To include deeper levels of associations pass a hash like this:
# #
# firm.to_xml :include => {:account => {}, :clients => {:include => :address}} # firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
Expand Down
6 changes: 6 additions & 0 deletions activerecord/test/cases/xml_serialization_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ def test_procs_are_called_on_object
assert_match %r{<nationality>Danish</nationality>}, xml assert_match %r{<nationality>Danish</nationality>}, xml
end end


def test_dual_arity_procs_are_called_on_object
proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
xml = authors(:david).to_xml(:procs => [ proc ])
assert_match %r{<name-reverse>divaD</name-reverse>}, xml
end

def test_top_level_procs_arent_applied_to_associations def test_top_level_procs_arent_applied_to_associations
author_proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') } author_proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') }
xml = authors(:david).to_xml(:procs => [ author_proc ], :include => :posts, :indent => 2) xml = authors(:david).to_xml(:procs => [ author_proc ], :include => :posts, :indent => 2)
Expand Down

0 comments on commit c39151a

Please sign in to comment.