#ruby-on-rails #nokogiri #observer-pattern #bulkinsert #webhooks
#ruby-on-rails #nokogiri #наблюдатель-шаблон #bulkinsert #веб-крючки
Вопрос:
Я пишу веб-сервис rails-hooks, который получает массовые объекты во вложенном XML и должен сохранять определенные поля в каждом узле. Когда XML-данные попадают в мое действие create в моем 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, которая соответствует событиям в хэше, не содержит всех полей в хэше. Также я хочу сопоставить поле SENDER_MSISDN с MSISDN зарегистрированных пользователей перед сохранением. Обычно я бы использовал Nokogiri для анализа XML и последующего создания объектов модели в цикле, но я не могу этого сделать, поскольку rails автоматически преобразует его в хэш. У меня нет способа изменить структуру поступающего XML.Я безуспешно пытался найти подсказку о том, как это сделать.
Я на грани того, чтобы рвать на себе волосы из-за этого.
Ответ №1:
Для этого вам нужно будет написать некоторый ручной код. Как насчет чего-то вроде:
params["Events"]["RecordSet"]["Record"].each do |h|
ExternalEvent.create(h.merge({ :MSISDN => h["SENDER_MSISDN"] }))
end
Если вам нужно удалить определенные поля, вы можете использовать delete_if
метод для Hash
. Например:
h.merge(..).delete_if {|key, value| [ "DONT_WANT", "THIS"].include?(key) }
Ответ №2:
external_event = ExternalEvents.new(params[:Events][:RecordSet][:Record])
Это должно создать новый экземпляр с атрибутами, соответствующими парам ключ-значение в хэше записи, при условии, что имена ваших полей совпадают.
Используйте проверку модели в SENDER_MSISDN и наложите ограничение внешнего ключа на external_events.Столбец SENDER_MSISDN.