lib/undo/serializer/active_model.rb in undo-serializer-active_model-0.0.3 vs lib/undo/serializer/active_model.rb in undo-serializer-active_model-0.0.4

- old
+ new

@@ -13,42 +13,54 @@ def serialize(object) serializer(object).as_json end def deserialize(hash) - hash.each do |object_class, data| - next unless data.is_a? Hash - data.stringify_keys! + object_handler, data = hash.first + return unless data.is_a? Hash + data.stringify_keys! - object_class = object_class.to_s.camelize.constantize - object = object_class.where(id: data.fetch("id")).first_or_initialize + ActiveRecord::Base.transaction do + initialize_object(object_handler, data).tap do |object| + data.each do |field, value| + next if "id" == field && object.persisted? - data.each do |field, value| - next if "id" == field && object.persisted? - _, association = field.to_s.split("___") - if association - deserialize_association(association, value) - else - object.send "#{field}=", value # not public_send! + case field + when /___(.*)/ then deserialize_association object, $1, value + else deserialize_field object, field, value + end end - end - object.save! - return object + object.save! + end end + end private attr_reader :serializer_source def serializer(object) @serializer ||= serializer_source.call object end - def deserialize_association(association, values) + def deserialize_association(object, association, values) Array.wrap(values).each do |value| - deserialize(association.singularize => value) + deserialize object.public_send(association) => value end + end + + def deserialize_field(object, field, value) + object.send "#{field}=", value # not public_send! + end + + def initialize_object(object_handler, data) + id = data.fetch "id" + relation = case object_handler + when String, Symbol then object_handler.to_s.camelize.constantize + else object_handler end + + relation.where(id: id).first || relation.new(id: id) end end end end