Удалить расширение .xml из запроса ActiveResource
Я пытаюсь использовать ActiveResource для использования XML-данных из стороннего API. Я могу использовать приложение RESTClient для успешной аутентификации и выполнения запросов. Я закодировал свое приложение, и когда я делаю запрос, я получаю ошибку 404. Я добавил:
ActiveResource::Base.logger = Logger.new(STDERR)
в файл development.rb и выяснил проблему. API отвечает данными xml на запросы, которые НЕ заканчиваются на xml. EG, это работает в RESTClient:
https://api.example.com/contacts
но вместо этого ActiveResource отправляет этот запрос
https://api.example.com/contacts.xml
Есть ли какой-нибудь "хороший" способ снять расширение из запроса, генерируемого ActiveResource?
Спасибо
Ответы
Ответ 1
Вероятно, вам необходимо переопределить метод element_path в вашей модели.
В соответствии с API, текущее определение выглядит следующим образом:
def element_path(id, prefix_options = {}, query_options = nil)
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
"#{prefix(prefix_options)}#{collection_name}/#{id}.#{format.extension}#{query_string(query_options)}"
end
Удаление части. # {format.extension} может сделать то, что вам нужно.
Ответ 2
Вы можете исключить строку формата из путей:
class MyModel < ActiveResource::Base
self.include_format_in_path = false
end
Ответ 3
Вы можете переопределить методы ActiveResource:: Base
Добавьте этот lib в каталог /lib/active _resource/extend/, не забудьте раскомментировать
"config.autoload_paths + =% W (# {config.root}/lib)" в config/application.rb
module ActiveResource #:nodoc:
module Extend
module WithoutExtension
module ClassMethods
def element_path_with_extension(*args)
element_path_without_extension(*args).gsub(/.json|.xml/,'')
end
def new_element_path_with_extension(*args)
new_element_path_without_extension(*args).gsub(/.json|.xml/,'')
end
def collection_path_with_extension(*args)
collection_path_without_extension(*args).gsub(/.json|.xml/,'')
end
end
def self.included(base)
base.class_eval do
extend ClassMethods
class << self
alias_method_chain :element_path, :extension
alias_method_chain :new_element_path, :extension
alias_method_chain :collection_path, :extension
end
end
end
end
end
end
в модели
class MyModel < ActiveResource::Base
include ActiveResource::Extend::WithoutExtension
end
Ответ 4
Намного проще переопределить аксессоры _path
, упомянутые в этом ответе, на основе класса, а не на общесистемных приложениях ActiveResource, может влиять на другие ресурсы или драгоценные камни, которые зависят от ActiveResource.
Просто добавьте методы непосредственно в свой класс:
class Contact < ActiveResource::Base
def element_path
super.gsub(/\.xml/, "")
end
def new_element_path
super.gsub(/\.xml/, "")
end
def collection_path
super.gsub(/\.xml/, "")
end
end
Если вы получаете доступ к нескольким ресурсам RESTful внутри одного API, вы должны определить свой собственный базовый класс, где может существовать общая конфигурация. Это гораздо лучшее место для пользовательских методов _path
:
# app/models/api/base.rb
class Api::Base < ActiveResource::Base
self.site = "http://crazy-apis.com"
self.username = "..."
self.password = "..."
self.prefix = "/my-api/"
# Strip .xml extension off generated URLs
def element_path
super.gsub(/\.xml/, "")
end
# def new_element_path...
# def collection_path...
end
# app/models/api/contact.rb
class Api::Contact < Api::Base
end
# app/models/api/payment.rb
class Api::Payment < Api::Base
end
# Usage:
Api::Contact.all() # GET http://crazy-apis.com/my-api/contacts
Api::Payment.new().save # POST http://crazy-apis.com/my-api/payments