2011-06-10 15 views
5

Estoy tratando de usar el Basecamp Classic API (http://developer.37signals.com/basecamp/comments.shtml). La versión actual de basecamp-wrapper me daba ajustes, una de las cosas era porque las respuestas json incluyen salida de paginación, mientras que las xml no. Esa fue una solución fácil, pero el problema es que la estructura de la url no está estandarizada.¿Cómo uso la API de Basecamp actual con ActiveResource?

La API especifica algunas cosas similares, lo que me lleva a pensar que sería simplemente separar la ruta del elemento y las rutas de recolección.

Get recent comments (for a commentable resource) 
GET /#{resource}/#{resource_id}/comments.xml 

Update comment 
PUT /comments/#{id}.xml 

He hecho varios intentos en este y realmente no he tenido éxito. Intentar manejar comentarios como este es hacky en el mejor de los casos, y en realidad no funciona porque el element_path es diferente de 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") 

Esto funciona hasta el update_attribute, que en realidad está recibiendo la url no anidada adecuada y se trata de hacer una solicitud PUT que falla.

¿Por qué esto no funciona para la actualización? ¿Cómo manejo los diferentes recursos principales de una mejor manera?

Cualquier consejo sería increíble. :)

+0

antes de responder, tengo curiosidad si algo como [de forma remota] (https://github.com/wegowise/remotely) funcionaría para usted? – 20man

+0

Posiblemente lo haría. Esto ya no es importante para mí, y ahora esto se llama Basecamp Classic. – excid3

Respuesta

0

Si intenta hackear ActiveResource, no va a pasar un buen rato.

No utilizaría prefix, y en su lugar definiría métodos en los recursos principales para obtener los recursos secundarios, usando 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 

La forma de usar estos recursos corresponde a las rutas que se llama.

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 
Cuestiones relacionadas