2010-07-21 24 views
14

Tôi đang cố gắng sử dụng ActiveResource để tiêu thụ dữ liệu xml từ API của bên thứ ba. Tôi có thể sử dụng ứng dụng RESTClient để xác thực thành công và đưa ra yêu cầu. Tôi đã mã hóa ứng dụng của mình và khi tôi đưa ra yêu cầu, tôi nhận được lỗi 404. Tôi đã thêm:Xóa phần mở rộng .xml khỏi yêu cầu ActiveResource

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

vào tệp development.rb của tôi và tìm ra sự cố. API đáp ứng với dữ liệu xml cho các yêu cầu KHÔNG kết thúc bằng xml. EG, công trình này trong RESTClient:

https://api.example.com/contacts 

nhưng ActiveResource đang gửi yêu cầu này thay vì

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

Liệu có cách nào "đẹp" cách để tước phần mở rộng từ yêu cầu được tạo ra bởi ActiveResource?

Cảm ơn

Trả lời

6

Bạn có thể cần ghi đè phương thức element_path trong mô hình của mình.

Theo API, defintion hiện trông như thế này:

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 

Loại bỏ cáC# {} format.extension phần có thể làm những gì bạn cần..

+0

Vâng, đây hiện các trick. Tôi tìm thấy bài viết này đi sâu hơn về làm việc với ActiveResource và API. http://www.quarkruby.com/2008/3/11/consume-non-rails-style-rest-apis – Matt

6

Bạn có thể ghi đè phương pháp ActiveResource :: Base

Thêm lib này trong/lib/active_resource/mở rộng/thư mục đừng quên bỏ ghi chú
"config.autoload_paths + =% W (# {config. gốc}/lib)" trong 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 

trong mô hình

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

Lưu ý, như của đường ray 3, bạn có thể muốn đặt điều này dưới/extras trong thư mục cấp cao nhất của ứng dụng của bạn (thay vì dưới/lib), vì bây giờ đường ray thư mục sẽ tự động tải nếu bạn bỏ ghi chú chính xác như trong config/application.rb. – benvolioT

+0

Đây là một giải pháp khá nặng tay giúp thay đổi hành vi của ứng dụng * ActiveResource * rộng. Một giải pháp địa phương hóa hơn có thể tốt hơn, tùy thuộc vào yêu cầu. – meagar

4

Đơn giản hơn để ghi đè các đối tượng truy nhập _path được đề cập trong this answer trên cơ sở từng lớp, thay vì ứng dụng ActiveResource trên bản vá có thể can thiệp vào các tài nguyên hoặc đá quý khác phụ thuộc vào ActiveResource.

Chỉ cần thêm các phương pháp trực tiếp đến lớp học của bạn:

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 

Nếu bạn đang truy cập nhiều tài nguyên RESTful trong cùng một API, bạn nên xác định lớp cơ sở riêng của bạn, nơi cấu hình chung có thể cư trú. Đây là một nơi tốt hơn để tùy chỉnh _path phương pháp:

# 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

Bạn có thể loại trừ các chuỗi định dạng từ đường dẫn với:

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

Lưu ý rằng điều này chỉ hoạt động như ActiveResource 4. Nếu bạn đang mắc kẹt trên 3.2.x hoặc trước đó, nó sẽ tăng một ngoại lệ. – MrTheWalrus

Các vấn đề liên quan