ruby-on-rails - 如何将当前的 Basecamp API 与 ActiveResource 结合使用?

标签 ruby-on-rails ruby-on-rails-3 api activeresource basecamp

我正在尝试使用 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


我在这方面做了几次尝试,但都没有真正成功。尝试处理这样的评论充其量是hacky,并且实际上不起作用,因为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

关于ruby-on-rails - 如何将当前的 Basecamp API 与 ActiveResource 结合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6302051/

相关文章:

ruby-on-rails - 如何在Elasticsearch上设置日期和模糊标题搜索

ruby-on-rails - 创建时的 Ruby (Rails) 字符串操作

ruby-on-rails - 使用 rbenv 和多个项目随着时间的推移维护 gems

ruby-on-rails-3 - 关闭 Rails 3 中的 CSRF token

javascript - Rails渲染JS部分打印代码到页面

ruby-on-rails - 如何垂直显示 simple_form

javascript - 维基百科 API 和 JSON

api - 使用额外数据扩展资源端点?

c# - 如何获取Google+的帖子数据(点赞-分享-评论)?

ruby-on-rails - 没有 Devise 的 Omniauth 和 google oauth2 错误 - Rails 4