我正在编写一个rails web hooks服务使用者,它接收嵌套XML中的批量对象,并需要在每个节点中保存某些字段。当XML数据到达我在HooksController中的创建操作时,XML会自动转换为如下所示的哈希。
Parameters: {"Events"=>{"RecordSet"=>{"Record"=>[{"SENDER_LAST_NAME"=>"Smith",
"SENDER_MIDDLE_NAME"=>"S.", "EVENT_ID"=>"3904", "SENDER_FIRST_NAME"=>"John",
"EVENT_TYPE"=>"Contact", "SENDER_MSISDN"=>"0723xxxxxx", "EVENT_DATE"=>"2011-05-31"},
{"SENDER_LAST_NAME"=>"Simiyu", "SENDER_MIDDLE_NAME"=>"N.",
"EVENT_ID"=>"2447", "SENDER_FIRST_NAME"=>"Steve", "EVENT_TYPE"=>"Tag",
"SENDER_MSISDN"=>"0720xxxxxxx", "EVENT_DATE"=>"2011-05-31"}]}, "xmlns"=>""}}
我不想存储每个对象的所有字段,因为我的ExternalEvents模型(对应于哈希中的Events)并没有包含哈希中的所有字段。此外,我希望在保存之前将字段SENDER_MSIDN与注册用户MSISDN相匹配。通常我会使用Nokogiri来解析XML,然后在循环中创建Model对象,但我不能这样做,因为rails会自动将其转换为哈希。我没有办法改变XML的结构。我试着寻找如何做到这一点的线索,但没有成功。
我差点被这个扯掉头发。
您需要编写一些手动代码来完成此操作。像这样的东西怎么样
params["Events"]["RecordSet"]["Record"].each do |h|
ExternalEvent.create(h.merge({ :MSISDN => h["SENDER_MSISDN"] }))
end
如果需要删除某些字段,则可以对Hash
使用delete_if
方法。例如:
h.merge(..).delete_if {|key, value| [ "DONT_WANT", "THIS"].include?(key) }
external_event = ExternalEvents.new(params[:Events][:RecordSet][:Record])
这应该创建一个新实例,其中的属性与Record哈希中的键值对匹配,假设字段名称匹配。
对SENDER_MISDN使用模型验证,并在external_events.SENDER_SISDN列上放置外键约束。