Jack
Jack

Reputation: 1163

Rails routes and rspec testing errors

I'm building a blog. I want to associate posts to users. I have the routes setup like so:

resources :users do
 resources :posts
end

resources :sessions, :only => [:new, :create, :destroy]

match '/signup', :to => 'users#new' 
match '/login',  :to => 'sessions#new'
match '/logout', :to => 'sessions#destroy' 

root :to => "pages#home"

This associates posts with users and when I do rake routes it looks like this:

user_posts GET    /users/:user_id/posts(.:format)          {:action=>"index", :controller=>"posts"}
user_posts POST   /users/:user_id/posts(.:format)          {:action=>"create", :controller=>"posts"}
new_user_post GET    /users/:user_id/posts/new(.:format)      {:action=>"new", :controller=>"posts"}
edit_user_post GET    /users/:user_id/posts/:id/edit(.:format) {:action=>"edit", :controller=>"posts"}
 user_post GET    /users/:user_id/posts/:id(.:format)      {:action=>"show", :controller=>"posts"}
 user_post PUT    /users/:user_id/posts/:id(.:format)      {:action=>"update", :controller=>"posts"}
 user_post DELETE /users/:user_id/posts/:id(.:format)      {:action=>"destroy", :controller=>"posts"}
     users GET    /users(.:format)                         {:action=>"index", :controller=>"users"}
     users POST   /users(.:format)                         {:action=>"create", :controller=>"users"}
  new_user GET    /users/new(.:format)                     {:action=>"new", :controller=>"users"}
 edit_user GET    /users/:id/edit(.:format)                {:action=>"edit", :controller=>"users"}
      user GET    /users/:id(.:format)                     {:action=>"show", :controller=>"users"}
      user PUT    /users/:id(.:format)                     {:action=>"update", :controller=>"users"}
      user DELETE /users/:id(.:format)                     {:action=>"destroy", :controller=>"users"}
    sessions POST   /sessions(.:format)                      {:action=>"create", :controller=>"sessions"}
 new_session GET    /sessions/new(.:format)                  {:action=>"new", :controller=>"sessions"}
     session DELETE /sessions/:id(.:format)                  {:action=>"destroy", :controller=>"sessions"}
                  /users/:user_id/posts/new(.:format)      {:controller=>"posts", :action=>"create"}
                  /users/:user_id/posts/:id/edit(.:format) {:controller=>"posts", :action=>"update"}
                  /users/:user_id/posts/:id(.:format)      {:controller=>"posts", :action=>"destroy"}
    signup        /signup(.:format)                        {:controller=>"users", :action=>"new"}
     login        /login(.:format)                         {:controller=>"sessions", :action=>"new"}
    logout        /logout(.:format)                        {:controller=>"sessions", :action=>"destroy"}
      root        /(.:format)                              {:controller=>"pages", :action=>"home"}

Before I made any other changes in the routes, I would then try to create new posts, edit and update them. But when I would try to create, edit or update posts I would get the errors:

No route matches "/users/1/posts/15/edit"
No route matches "/users/1/posts/new"

So then I played around and added this to my routes:

match '/users/:user_id/posts/new', :to => 'posts#create'
match '/users/:user_id/posts/:id/edit', :to => 'posts#update'
match '/users/:user_id/posts/:id', :to => 'posts#destroy'

After that, everything worked. Updating, creating, editing, etc. But then some of my tests were failing.

1) PostsController GET 'new' returns http success
 Failure/Error: get 'posts#new'
 ActionController::RoutingError:
   No route matches {:controller=>"posts", :action=>"posts#new"}
 # ./spec/controllers/posts_controller_spec.rb:13:in `block (3 levels) in <top (required)>'

2) PostsController GET 'edit' returns http success
 Failure/Error: get 'edit'
 ActionController::RoutingError:
   No route matches {:controller=>"posts", :action=>"edit"}

I know that using those routes everything worked, but are they wrong and I need to route them some other way? Or is there something I can change in the tests to make them pass?

Thanks.

Upvotes: 1

Views: 1459

Answers (1)

zetetic
zetetic

Reputation: 47548

get 'edit' => No route matches {:controller=>"posts", :action=>"edit"}

fails because the route requires a :user_id in the params. You want:

get 'edit', :user_id => 1

btw it seems you are overriding the 'resourceful' routes with your match statements, eg:

match '/users/:user_id/posts/new', :to => 'posts#create'

overrides the new_user_post route created by the resources statement. Are you sure that's what was intended? You generally want to have /users/:user_id/posts/new to go to the new action (rendering a form) rather than the create action (handling the posted form).

Upvotes: 2

Related Questions