Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

RoutingError when using form_for, nested resources and :as

#5798

I get the following error when trying to use form_for with nested resources, the nested resource route being defined with the :as options:

No route matches {:controller=>"blog_post_comments", :blog_post_id=>#<BlogPost id: 1, title: "asdfasdf" >}

Here is how to replicate this error:
1) Create a new rails3 app
2) Generate two models: BlogPost, BlogPostComment
3) Setup these routes:

resources :blog_posts do
  resources :blog_post_comments, :as => 'comments'
end

4) Add this form_for in views/posts/show.html.erb:

<%= form_for [@blog_post, @blog_post.comments.build] do |f| %>
  <%= f.submit 'Send' %>
<% end %>

5) Use the scaffolded views/controller to create a new post

Now, I expect you to see the same error as shown above. Remove the :as parameter in routes, and the error goes away.

I'm using rails 3-0-edge with ruby 1.9.2.

Reported by Rasmus Rønn Nielsen · October 13th, 2010 @ 09:54 AM

State: invalid
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Piotr Sarnacki
    Piotr Sarnacki

    The reason of this error is that form_for does not know about routes. form_for uses polymorphic_url for generating url, which is based on model names. If you have models BlogPost and BlogPostComment, their names are blog_post and blog_post_comment and form_for will simply use it, regardless routes matches that or not.

    October 13th, 2010 @ 10:18 AM

  2. Rasmus Rønn Nielsen
    Rasmus Rønn Nielsen

    Thank you very much for that quick response.

    So I must accept named routes like blog_post_blog_post_comments_path if I want to use form_for? Or is there a "Rails way" of doing this I am not aware of?

    October 13th, 2010 @ 10:22 AM

  3. Santiago Pastorino
    Santiago Pastorino
    • State changed from new to invalid
    • Importance changed from to Low

    October 13th, 2010 @ 01:52 PM

  4. Piotr Sarnacki
    Piotr Sarnacki

    If you want to use :as option like that, you can set url for form_for manually. I don't know if there is some other option. I will comment here if I find something.

    October 13th, 2010 @ 01:56 PM

  5. David Morton
    David Morton

    The reason of this error is that form_for does not know about routes. form_for uses polymorphic_url for generating url, which is based on model names

    I see several variations on this, all with a "wontfix" type attitude. I ask, why? It seems that the very name "polymorphic_url" has to do with urls, which are directly related to routes. It just doesn't make any sense to ignore the routes!

    November 18th, 2010 @ 04:44 AM

  6. Piotr Sarnacki
    Piotr Sarnacki

    @David: polymorphic_url is dumb in a way that it just maps model name to route:

    polymorphic_url(Post.find(1), Comment.find(2)) #=> /posts1/comments/2
    polymorphic_url(Post::Comment.find(1)) #=> /post_comments/1
    

    It can't analyze the routes and guess if you want to use some specific route that you renamed.

    November 18th, 2010 @ 05:02 AM

  7. bingbing