Как использовать текущий API Basecamp с ActiveResource? - PullRequest
5 голосов
/ 10 июня 2011

Я пытаюсь использовать API Basecamp Classic (http://developer.37signals.com/basecamp/comments.shtml). Текущая версия basecamp-обертки дает мне припадки, одна из причин состояла в том, что ответы 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, который завершается неудачей.

Почему это не работает для обновления? Как лучше обрабатывать различные родительские ресурсы?

Любые советы будут великолепны. :)

1 Ответ

0 голосов
/ 24 февраля 2013

Если вы попытаетесь взломать 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
...