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.

Routes that specify a custom controller name aren't found in functional tests

#4623

Rails versions: 3.0.0.beta3

Please see attached project.

When running 'rake test:functionals" you should notice that the tests throw a number of errors while running, indicating that the specified routes could not be found. It would appear that the functional tests aren't properly picking up the routing from routes.rb when a custom controller is specified for the route.

Further background:
The following is specified in routes.rb:

resources :posts, :controller => "CustomPosts"

The project has both a CustomPostsController and a CustomPost model attribute.

When running 'rake test:functionals" I'm seeing the following errors (small excerpt):

6) Error:
test_should_show_post(CustomPostsControllerTest):
ActionController::RoutingError: No route matches {:id=>"980190962", :controller=>"custom_posts", :action=>"show"}

7) Error:
test_should_update_post(CustomPostsControllerTest):
ActionController::RoutingError: No route matches {:id=>"980190962", :post=>{"body"=>"MyText", "created_at"=>2010-05-17 05:49:16 UTC, "id"=>980190962, "title"=>"MyString", "updated_at"=>2010-05-17 05:49:16 UTC}, :controller=>"custom_posts", :action=>"update"}

Reported by Jury · May 17th, 2010 @ 07:11 AM

State: invalid
Milestone: none
Assigned to: Yehuda Katz (wycats) Yehuda Katz (wycats)
Importance: none

Activity

  1. Jury
    Jury

    Adding the following to routes.rb changes the problem slightly:

    resources :custom_posts
    

    Now, the errors about unrecognized paths go away, but we're left with the redirect assertions not being happy:

    1) Failure:
    test_should_create_post(CustomPostsControllerTest) [test/functional/custom_posts_controller_test.rb:24]:
    Expected response to be a redirect to http://test.host/posts/980190963 but was a redirect to http://test.host/custom_posts/980190963

    2) Failure: test_should_update_post(CustomPostsControllerTest) [test/functional/custom_posts_controller_test.rb:39]:
    Expected response to be a redirect to http://test.host/posts/980190962 but was a redirect to http://test.host/custom_posts/980190962

    I'm no expert on the source, but in doing some piecing together of the problem, it looks the fundamental issue is that each test asks its @controller to build a URI for the request — that's all well and good except it doesn't appear that the controller is smart enough to know how access to it has been specified in routes.rb. This problem looks pretty deep rooted, and my familiarity with the rails source isn't in-depth to know beyond a doubt that this is the case.

    Adding the controller to routes.rb seems to make the routing mechanisms happy, but then since the tests are using the path convenience methods based on the desired route (in this example, "resources :posts, :controller => "CustomPosts") as opposed to the paths based on "resources :custom_posts" the assertions aren't happy.

    May 18th, 2010 @ 03:28 AM

  2. Jury
    Jury
    • Assigned user set to Yehuda Katz (wycats)

    May 18th, 2010 @ 05:04 AM

  3. José Valim
    José Valim

    Have you tried giving :controller => "custom_posts" instead?

    May 18th, 2010 @ 01:27 PM

  4. Jury
    Jury

    Success! Looks like specifying

    :controller => "custom_posts"
    

    works great. Is the the proper way to specify this in routes.rb? It seemed that "CustomPosts" worked well for the router, just not the tests.

    Also, and I apologize in advance for glomming on to this, but I've noticed in my views that I now have to use the "posts_path(@post)" method for specifying things like the following

    <% @posts.each do |post| %>

    <td><%= post.title %></td>
    <td><%= post.body %></td>
    <td><%= link_to 'Show', post_path(post) %></td>
    <td><%= link_to 'Edit', edit_post_path(post) %></td>
    <td><%= link_to 'Destroy', post_path(post), :confirm => 'Are you sure?', :method => :delete %></td>
    

    This appears to be because each post object only knows how to create paths that use "custom_post" as the controller. Is there any way to tell the controller to use just "post" in the URIs it creates (which is what is specified in routes.rb)? That way I can just leave this as:

    <% @posts.each do |post| %>

    <td><%= post.title %></td>
    <td><%= post.body %></td>
    <td><%= link_to 'Show', post %></td>
    <td><%= link_to 'Edit', edit_post_path(post) %></td>
    <td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
    

    May 18th, 2010 @ 06:54 PM

  5. José Valim
    José Valim
    • State changed from new to invalid

    Yes, if you use non conventional routes, Rails cannot guess it anymore.

    May 18th, 2010 @ 07:05 PM