(Edited 2 Sept 2011: Please see instead the updated post here: ActiveRecord from_xml (and from_json) part 2.)
Unless I’m missing something, the default rails from_json and from_xml methods don’t work with data that have associated objects. Here are routines that work for some simple examples I’ve tested. I placed this code in vendor/rails/activerecord/lib/active_record/base.rb within the ActiveRecord::Base class, but there might be a better place to put it.
def self.from_hash( hash )
h = hash.dup
h.each do |key,value|
case value.class.to_s
when 'Array'
h[key].map! { |e|
Object.const_get(key.camelize.singularize).from_hash e }
when 'Hash'
h[key] = Object.const_get(key.camelize).from_hash value
end
end
self.new h
end
def self.from_json( json )
hash = ActiveSupport::JSON.decode json
self.from_hash hash
end
# The xml has a surrounding class tag (e.g. ship-to),
# but the hash has no counterpart (e.g. 'ship_to' => {} )
def self.from_xml( xml )
hash = Hash.from_xml xml
self.from_hash hash[self.to_s.underscore]
end
Also available on pastie.
Example usage, using the to_xml example:
xml = firm.to_xml :include => [ :account, :clients ]
firm = Firm.from_xml xml
Note: this only works if the classes of the nested objects are canonically named. If any of your associations use the :class_name option, you will probably need to update this code to discover the proper class names.
I just wrote this a couple hours ago, so please consider this to be an alpha version.
ActiveRecord from_json and from_xml
(Edited 2 Sept 2011: Please see instead the updated post here: ActiveRecord from_xml (and from_json) part 2.)
Unless I’m missing something, the default rails from_json and from_xml methods don’t work with data that have associated objects. Here are routines that work for some simple examples I’ve tested. I placed this code in vendor/rails/activerecord/lib/active_record/base.rb within the ActiveRecord::Base class, but there might be a better place to put it.
Also available on pastie.
Example usage, using the to_xml example:
Note: this only works if the classes of the nested objects are canonically named. If any of your associations use the :class_name option, you will probably need to update this code to discover the proper class names.
I just wrote this a couple hours ago, so please consider this to be an alpha version.