Как я могу сделать ActiveResource XML-анализ более согласованным? - PullRequest
3 голосов
/ 27 января 2011

Я использую ActiveResource для использования веб-сервиса REST, предоставляемого Redmine (инструмент отслеживания ошибок). Этот веб-сервис производит XML следующим образом:

<custom_field name="Issue Owner" id="15">Fred Fake</custom_field> 
<custom_field name="Needs Printing" id="16">0</custom_field> 
<custom_field name="Review Assignee" id="17">Fran Fraud</custom_field> 
<custom_field name="Released On" id="20"></custom_field> 
<custom_field name="Client Facing" id="21">0</custom_field> 
<custom_field name="Type" id="22">Bug</custom_field> 
<custom_field name="QA Assignee" id="23"></custom_field> 
<custom_field name="Company Name" id="26"></custom_field> 
<custom_field name="QA Notes" id="27"></custom_field> 
<custom_field name="Failed QA Attempts" id="28">2</custom_field> 

Однако, когда ActiveResource анализирует это, и я перебираю результаты, распечатывая их, я получаю:

Fred Fake
0
Fran Fraud
#<Redmine::Issue::CustomFields::CustomField:0x5704e95d>
0
Bug
#<Redmine::Issue::CustomFields::CustomField:0x32fd963>
#<Redmine::Issue::CustomFields::CustomField:0x3a68f437>
#<Redmine::Issue::CustomFields::CustomField:0x407964d6>
2

Правильно, он выбрасывает всю информацию об атрибутах из всего, что имеет значение, но сохраняет информацию об атрибутах из пустых элементов.

Излишне говорить, что это довольно сложно, когда вы пытаетесь найти значение для идентификатора 15 (или чего-то еще). Теперь я могу ссылаться на вещи по их положению, но это очень хрупко, потому что эти элементы могут измениться в будущем. Я предполагаю, что должен быть какой-то способ заставить ActiveResource хранить информацию об атрибутах, но так как я не делаю ничего особенного.

(мое расширение ActiveResource имеет длину всего пять строк: оно расширяет ActiveResource, определяет URL, имя пользователя и пароль службы, и все).

Итак, кто-нибудь знает, как заставить ActiveResource так странно не анализировать этот XML?

1 Ответ

1 голос
/ 12 октября 2012

Это известная проблема с ActiveResource, по-видимому:

https://github.com/rails/rails/issues/588

К сожалению, с этим ничего не поделать, и проблема была закрыта.Если вам это нравится, код Rails 3 для обновления ActiveResource и Hash.from_xml, чтобы сохранить все атрибуты, представлен ниже, и вы можете создать специальную версию в своем модуле Redmine, чтобы исправить это:

https://gist.github.com/971598

Обновление:

Альтернатива, как представляется ActiveResource не будет частью ядра Rails 4 и будет запущенав качестве отдельной жемчужины можно было бы использовать альтернативный ORM для REST API, например Her .

Her , позволяющий использовать пользовательский анализатор для вашего XML.Это пример пользовательского анализатора с именем Redmine :: ParseXML:

https://gist.github.com/3879418

Итак, все, что вам нужно сделать, это создать файл, такой как config / initializers / her.rb:

Her::API.setup :url => "https://api.xxxxx.org" do |connection|
  connection.use Faraday::Request::UrlEncoded
  connection.use Redmine::ParseXML
  connection.use Faraday::Adapter::NetHttp
end

и вы получите хеш, как показано ниже:

#<Redmine::Issue(issues) issues={:attributes=>{:type=>"array", :count=>1640}, 
:issue=>{:id=>4326, 
    :project=>{:attributes=>{:name=>"Redmine", :id=>1}}, 
    :tracker=>{:attributes=>{:name=>"Feature", :id=>2}}, 
    :status=>{:attributes=>{:name=>"New", :id=>1}}, 
    :priority=>{:attributes=>{:name=>"Normal", :id=>4}}, 
    :author=>{:attributes=>{:name=>"John Smith", :id=>10106}}, 
    :category=>{:attributes=>{:name=>"Email notifications", :id=>9}}, 
    :subject=>"\n      Aggregate Multiple Issue Changes for Email Notifications\n    ",
    :description=>"\n      This is not to be confused with another useful proposed feature that\n      would do digest emails for notifications.\n    ", 
    :start_date=>"2009-12-03", 
    :due_date=>{}, 
    :done_ratio=>0, 
    :estimated_hours=>{}, 
    :custom_fields=>{
       :custom_field=>[
          {:attributes=>{:name=>"Issue Owner", :id=>15}, "value"=>"Fred Fake"},
          {:attributes=>{:name=>"Needs Printing", :id=>16}, "value"=>0}, 
          {:attributes=>{:name=>"Review Assignee", :id=>17}, "value"=>"Fran Fraud"},
          {:attributes=>{:name=>"Released On", :id=>20}}, 
          {:attributes=>{:name=>"Client Facing", :id=>21}, "value"=>0}, 
          {:attributes=>{:name=>"Type", :id=>22}, "value"=>"Bug"}, 
          {:attributes=>{:name=>"QA Assignee", :id=>23}}, 
          {:attributes=>{:name=>"Company Name", :id=>26}}, 
          {:attributes=>{:name=>"QA Notes", :id=>27}}, 
          {:attributes=>{:name=>"Failed QA Attempts", :id=>28}, "value"=>2}]},
    :created_on=>"Thu Dec 03 15:02:12 +0100 2009", 
    :updated_on=>"Sun Jan 03 12:08:41 +0100 2010"}}>
...