Simply Restful in Rails Edge

Posted by rick August 01, 2006 @ 03:22 AM

David committed the simply_restful plugin to the rails this afternoon, ensuring its inclusion with the next release of Rails. Beware, there are a few API changes from the plugin, and a nice new feature:


# OLD
map.resource :post
map.resource :comment, :path_prefix => '/posts/:post_id'
map.resource :trackback, :path_prefix => '/posts/:post_id'

# NEW
map.resources :posts do |posts|
  posts.resources :comments, :trackbacks
end

Nesting the resource blocks will automatically set the path prefix from the parent’s path.

There may be some bugs introduced in the move from plugin to core, so try upgrading (and remember to remove the plugin!) and let us know if you find anything. I have the current version running on a couple apps now, so things should be working.

Update: There is one more restriction I forgot to mention. The _method hack only works on POST methods now. It is no longer valid to link to a URL like /articles/1?_method=delete. Let’s not open that can of worms again.

Tip #1: Use my routing navigator plugin to get a handle on what routes are being created.

Tip #2: Use the new *_path routes if you want your routes to have just the path (’/articles/1’) instead of the whole url with protocal and host.

20 comments

Comments

  1. Matt Todd on 01 Aug 03:50:

    Beautiful! Though I wish map.resources didn’t have to be repeated, though it is 33% shorter in that regard anyhow, haha!

    Thanks for moving more towards RESTfulness. It’s making me restless to build more apps more often in Ruby and Rails!

    M.T.

  2. Nate Kontny on 01 Aug 04:24:

    Awesome. Great work on this stuff, I love it. And I really appreciate what you guys have built. Just recently found some time to start refactoring some code to get on the restful routes path, and I am a total convert.

    Here’s something I struggled with using the restful plugin, and I didn’t want to send this to Trac as I have yet to be able to create a test case that replicates the problem, but I may as well talk about it with someone :)

    After installing simply_restful and moving to edge things were pretty good, except for the selenium_testing plugin. Now, I’m sure this could totally be due to something that that plugin may still need to upgrade to for this latest code. So I started updating the routes.rb file it uses, but I still ran into problems with an endless loop that it started having.

    It seemed the problem was in simply_restfuls request.rb. It seemed as if in the selenium_test case (not my own app and its routing) method_with called method_without which called method with called method_with, and on and on.

    I updated request.rb and init.rb to only alias “method” once, since I felt that’s all it really might need under a different way of extending ActionController.

    Here’s what I’m talking about:

    http://pastie.caboo.se/6834

    And got rid of the send to :include in the init.rb of the plugin. Am I missing the reason why it’s written the way it is? Any clues as to why the selenium_testing plugin routing might lead to endless loops in that request.rb?

    If it helps, here’s the selenium_testing routes, that I started hacking on to get to work with edge:

    http://pastie.caboo.se/6835

  3. rick on 01 Aug 05:29:

    Sounds like a case of two plugins stepping on each other’s toes. Does this still occur on edge rails? Simply Restful’s AbstractRequest#method method isn’t monkey patched with alias anymore.

  4. flevour on 01 Aug 11:06:

    Now we need an official Rails manual/howto to learn how to grok the RESTful Rails Way.

  5. Jan Prill on 01 Aug 12:45:

    Hi there,

    I’ve made my first steps with REST by starting with simply_restful and now purely with edge rails. To get a simple restful controller working was possible, but now I’m stuck on things like adding comments to a post and so on. I’d really like to use something elegant like /posts/1/comments;new by using only restful controllers but don’t get it yet.

    Is there already something like a low level tutorial for a small restful blog application? IMHO a blog post on this from someone who has the insights would be a great learning resource for REST-beginners like myself…

    Cheers, Jan

  6. Bil on 01 Aug 12:46:

    Typo ? “to the rails” : “to the rails core”

  7. rick on 01 Aug 15:10:

    Jan:

    
    map.resources :posts do |posts|
      posts.resources :comments
    end
    
    # in the controller
    def create
      @post = Post.find(params[:post_id])
      @comment = @post.comments.create(params[:comment])
    end
    

    There’s no real documentation out there yet, but I’m sure it’s coming. Keep in mind this is new, officially unreleased, and we’re all still figuring out how to use this effectively.

  8. Josh Peek on 01 Aug 15:59:

    Has the API for the hidden method hack changed?

    I’d like to just changed the method in the form and Rails insert the hack if it needs to.

    <% form_for …, :method => :put do |f| -%> <%= hidden_field_tag :_method, :put %> <% end -%>

    As of r4644, this doesn’t work. You still have to set the method to :post and then do the hack. That doesn’t seem right.

  9. Rahsun McAfee on 01 Aug 16:21:

    You guys ROCK! ..... need I say more?

  10. rick on 01 Aug 17:13:

    Josh: It was broken for a few revisions, though I don’t recall which one I fixed it on. Check out actionpack/test/controller/request_test.rb to see the tests for the method hacking.

    There is one new restriction that I forgot to mention, you can only use _method hacks for POST.

  11. Ryan on 01 Aug 17:36:

    Rick,

    Is that really the “rest-ful” way? Shouldn’t there be a comment controller that handles all the CRUD actions against a comment?

    —Ryan

  12. rick on 01 Aug 20:22:

    There is. I guess you’d know if I had specified :) Just to be clear, that #create method above should be in a comments controller. Notice since it’s declared inside the posts resource block, it assumes a path_prefix of ’/posts/:post_id’. You can then use that to set the Comment’s post_id.

  13. Chris on 02 Aug 03:53:

    All,

    I have been hearing a lot about REST lately but even looking at the example above – I just don’t get it.

    Where might I find an article that more clearly explains what REST is and how Ruby can use it.

    Thanks, Chris

  14. Ernie on 02 Aug 14:05:

    Chris, there is a great explanation here: http://www.ryandaigle.com/articles/2006/08/01/whats-new-in-edge-rails-simply-restful-support-and-how-to-use-it

  15. Ryan on 02 Aug 15:27:

    Rick,

    Your explanation just made this whole REST idea click for me… Thanks!

    And thanks to DHH, this is awesome.

    It’s amazing that something so simple as conforming to CRUD could lead to simpler apps…

    —Ryan

  16. Joshua on 02 Aug 23:58:

    Hi,

    
    ActionView::TemplateError: <path_to_app>/config/.. /
    /vendor/rails/actionpack/lib/action_controller/url_rewriter.rb:29:in  /
    `<<': cannot convert nil into String
    

    Just wondering if anyone else has encountered this error when doing functional testing on two nested resource blocks in the routes file.

    
    map.resources :posts do |posts|
     posts.resources :comments do |comments|
      comments.resources :extra
     end
    end
    

    In this example only the :extra functional test will give the error.

    The app works fine when its running though.

    By the way I’m loving this whole RESTful and design by CRUD stuff. Great work guys.

    Cheers, Josh

  17. dharana on 04 Aug 15:48:

    This is great! Is there any estimates for the next rails release? I would like to use the simply_restful plugin but I can’t afford to run edge rails.

    Regards, dharana

  18. monki on 04 Aug 16:43:

    I was curious about this stuff too, but at a bit of a loss. I took some time and managed to stumble my way through getting something setup. I decided to mimic scaffolding to give myself and others a nice point of reference and to demystify things. I wrote up my experiences, and I hope some people can find them helpful. Check it out here: http://monki.geemus.com/restful_blog/

  19. Ryan on 17 Aug 03:14:

    monki your URL is broken :(

  20. monki on 24 Aug 17:33:

    My tutorial didn’t manage to survive as long or as extensively as I might like. I did create a scaffold generator for restful controllers that some people might find useful (if they happen to check this somewhat old post/comments thread). You can grab a copy from: http://geemus.svnrepository.com/svn/rails/plugins/restful_scaffold/ README contains some simple usage instructions. Hope it helps somebody.