如何将当前的Basecamp API与ActiveResource一起使用?

问题描述

| 我正在尝试使用Basecamp Classic API(http://developer.37signals.com/basecamp/comments.shtml)。当前的basecamp-wrapper版本适合我,其中之一是因为json响应包含分页输出,而xml响应不包含分页输出。那是一个简单的解决方法,但是问题是url结构没有标准化。 API规定了一些类似的内容,这使我相信它只是将元素路径和收集路径分开。
Get recent comments (for a commentable resource)
GET /#{resource}/#{resource_id}/comments.xml

Update comment
PUT /comments/#{id}.xml
我为此做了几次尝试,但还没有真正成功。试图处理这样的注释充其量是不明智的,并且实际上不起作用,因为element_path与collection_path不同。
class Resource < ActiveResource::Base
  self.site = \"https://XXXX.basecamphq.com\"
  self.user = \"XXXX\"
  self.password = \"X\" # This is just X according to the API,I have also read nil works
  self.format = :xml # json responses include pagination crap

  # Override element path so it isn\'t nested
  class << self
    def element_path(id,prefix_options={},query_options={})
      prefix_options,query_options = split_options(prefix_options) if query_options.nil?
      \"#{collection_name}/#{URI.parser.escape id.to_s}.#{format.extension}#{query_string(query_options)}\"
    end
  end
end

class Project < Resource
end

class Message < Resource

  self.element_name = \"post\"
  self.prefix = \"/projects/:project_id/\"
  self.collection_name = \"posts\"

  def comments
    @comments ||= Comment.all(:params => {:resource => \"posts\",:resource_id => id})
  end
end

class Comment < Resource
  self.prefix = \"/:resource/:resource_id/\"
end

puts m = Message.first(:params => {:project_id => PROJECT_ID})
puts m = Message.find(m.id)
puts m.update_attribute(:title,\"name\")
这可以一直进行到update_attribute为止,后者实际上获得了正确的非嵌套url,并且发出了失败的PUT请求。 为什么此功能无法更新?如何更好地处理不同的父资源? 任何提示都很棒。 :)     

解决方法

        如果您尝试破解ActiveResource,那么您将不会过得很开心。 我不会使用
prefix
,而是会使用
find(:all,:from => \'\')
在父资源中定义用于获取子资源的方法。 http://api.rubyonrails.org/classes/ActiveResource/Base.html#method-c-find
class Resource < ActiveResource::Base
  self.site = \"https://XXXX.basecamphq.com\"
  self.user = \"XXXX\"
  self.password = \"X\" # This is just X according to the API,I have also read nil works
  self.format = :xml # json responses include pagination crap
end

class Project < Resource
  def messages
    @messages ||= Message.find(:all,:from => \"/projects/#{self.id}/posts.xml\")
  end
end

class Message < Resource
  self.element_name = \"post\"

  def comments
    @comments ||= Comment.find(:all,:from => \"/posts/#{self.id}/comments.xml\")
  end
end

class Comment < Resource
end
您使用这些资源的方式对应于所调用的路径。
project  = Project.find(1)               # GET /projects/1.xml
messages = project.messages              # GET /projects/1/posts.xml
message  = message.first
comments = message.comments              # GET /posts/1/comments.xml
comment.update_attribute(:title,\'name\')  # PUT /comments/1.xml