14

我正在尝试使用 ActiveResource 来使用来自第三方 API 的 xml 数据。我可以使用 RESTClient 应用程序成功进行身份验证并发出请求。我编写了我的应用程序,当我提出请求时,我收到 404 错误。我补充说:

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

到我的 development.rb 文件并找出问题所在。API 以 xml 数据响应不以 xml 结尾的请求。例如,这适用于 RESTClient:

https://api.example.com/contacts

但 ActiveResource 正在发送此请求

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

无论如何,有没有“好”的方法从 ActiveResource 生成的请求中去除扩展?

谢谢

4

4 回答 4

13

You can exclude the format string from paths with:

class MyModel < ActiveResource::Base
  self.include_format_in_path = false
end
于 2013-12-06T22:04:53.907 回答
6

您可能需要覆盖模型中的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} 部分可能会满足您的需要。

于 2010-07-22T04:08:36.467 回答
6

您可以覆盖 ActiveResource::Base 的方法

在 /lib/active_resource/extend/ 目录中添加这个库,不要忘记在config/application.rb中取消注释
“config.autoload_paths += %W(#{config.root}/lib)”

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
于 2011-05-25T14:16:35.950 回答
5

逐个类地覆盖此答案_path中提到的访问器要简单得多,而不是在应用程序范围内对 ActiveResource 进行猴子修补,这可能会干扰依赖于 ActiveResource 的其他资源或 gem。

只需将方法直接添加到您的类中:

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

如果你在同一个 API 中访问多个 RESTful 资源,你应该定义你自己的基类来存放通用配置。_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
于 2012-08-03T22:02:33.807 回答