2010-07-21 12 views
14

Próbuję użyć ActiveResource do pobrania danych XML z interfejsu API innej firmy. Mogę używać aplikacji RESTClient, aby pomyślnie uwierzytelniać i wysyłać żądania. Zakodowałem moją aplikację i kiedy zgłoszę żądanie, otrzymuję błąd 404. Dodałem:Usuń rozszerzenie .xml z żądania ActiveResource

ActiveResource::Base.logger = Logger.new(STDERR) 

do mojego pliku development.rb i zorientowałem się, że problem. Interfejs API odpowiada danymi XML na żądania, które NIE kończą się na xml. EG, to działa w RESTClient:

https://api.example.com/contacts 

ale ActiveResource wysyła to żądanie zamiast

https://api.example.com/contacts.xml 

Czy mimo to „miły” sposób rozebrać rozszerzenie z żądania generowane przez ActiveResource?

Dzięki

Odpowiedz

6

Prawdopodobnie trzeba zastąpić metodę element_path w modelu.

Według API, obecna defintion wygląda następująco:

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 

Zdejmowanie # {} format.extension część może robić to, co trzeba..

+0

Tak, to załatwia sprawę. Znalazłem ten artykuł, który idzie głębiej na pracę z ActiveResource i API. http://www.quarkruby.com/2008/3/11/consume-non-rails-style-rest-apis – Matt

6

Można zastąpić metody ActiveResource :: Base

Dodaj lib/lib/active_resource/Wydłuż/katalogu nie zapomnij znak komentarza
„config.autoload_paths + =% m (# {config. korzeń}/Mb)” w konfiguracji/environment.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 

wzorcowy

class MyModel < ActiveResource::Base 
    include ActiveResource::Extend::WithoutExtension 
end 
+1

Uwaga, od szyn 3, możesz umieścić to w katalogu/dodatki w katalogu najwyższego poziomu aplikacji (zamiast under/lib), ponieważ to jest teraz, gdy szyny katalogów będą automatycznie ładowane, jeśli odkomentujesz poprawne jak w config/application.rb. – benvolioT

+0

To dość ciężkie rozwiązanie modyfikujące zachowanie aplikacji ActiveResource * *. Bardziej zlokalizowane rozwiązanie może być lepsze, w zależności od wymagań. – meagar

4

O wiele łatwiej jest zastąpić akcesory _path wymienione w this answer dla poszczególnych klas, a nie dla aplikacji ActiveResource z łataniem małp, które mogą zakłócać działanie innych zasobów lub klejnotów zależnych od ActiveResource.

Wystarczy dodać metod bezpośrednio do Twojej klasy:

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 

Jeśli masz dostęp do wielu zasobów w obrębie tej samej relaksującego API, należy zdefiniować własną klasę bazową gdzie mogą przebywać typowej konfiguracji. Jest to o wiele lepsze miejsce dla niestandardowych _path metod:

# 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 
11

można wykluczyć ciąg formatu ze ścieżek z:

class MyModel < ActiveResource::Base 
    self.include_format_in_path = false 
end 
+1

Należy zauważyć, że działa to tylko z ActiveResource 4. Jeśli utkniesz w wersji 3.2.x lub wcześniejszej, spowoduje to zgłoszenie wyjątku. – MrTheWalrus

Powiązane problemy