问题描述
|
我正在尝试使用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