I’ve been working on a wrapper library for the Pivotal Tracker API, and found it difficult to find a single source of documentation on how to map deep nested restful Rails routes into ARes classes.
Using the classic ‘Blog posts’ and ‘Comments’ as an example, you have RESTful URL’s like these to work with:
/posts
/posts/1
/posts/1/comments
/posts/1/comments/1
The documentation is a little hazy on how you map these, in particular the ‘comments’, in ARes.
After a little poking around, I’ve come up with the following solution:
class Post < ActiveResource::Base
self.site = "http://site.com/"
def comments(scope = :all)
Comment.find(scope, :params => {:post_id => self.id})
end
def comment(id)
comments(id)
end
end
class Comment < ActiveResource::Base
# :post_id gets swapped out by ARes based on the :prefix_options hash
self.site = "http://site.com/posts/:post_id"
def post
Post.find(self.prefix_options[:post_id])
end
def post=(post)
self.prefix_options[:post_id] = post.id
end
end
You can then use these classes like this:
# Find post id 1
post = Post.find(1)
# Find all comments for a post
post.comments.each { |comment| puts comment.body }
# Find comment id 1 for a post
comment = post.comment(1)
# Create a new comment and assign it to a post
comment = Comment.new :body => body_text
comment.post = post
comment.save
The key to all this is the :prefix_options
hash, which is not very well documented, and allows you to create the ‘belongs_to’ relationship which nested resources typically represent in a Rails app.