Question

I'm working on a project management web app and I have to pages for viewing projects. One is for viewing all the projects, and the other one is for management of of the project the user owns (i.e is administrator).

As it is now one can reach the overview page for projects by the use of 'projects_path' (/projects). However for the project management page I want to have another url, 'projects/manage', and it's here I need help.

I have tried the following:

routes.rb:

match "/projects/manage" => "projects#manage", :as => 'manage_projects'

view:

<%= link_to "Manage projects", manage_projects_path %>

Which raises the following error:

Couldn't find Project with id=manage
app/controllers/projects_controller.rb:62:in `show'

Why do it direct me to the action 'show' when I've explicitly set it to direct me to 'manage' (projects#manage)? Apparently it want an 'id', which shouldn't be the case here because I want to show all the projects (that the user owns), not a specific.

How can I solve this?

Was it helpful?

Solution

If you are performing the manage action on multiple projects it is better to write collection action in following way,

 resources :projects do
   collection do
    get "manage" 
   end 
 end

This will provide you the route /projects/manage, will automatically match the route to manage action and every thing will be as per the REST conventions.

OTHER TIPS

When your Rails application receives an incoming request

GET /projects/17

it asks the router to match it to a controller action. If the first matching route is

match "/projects/:id" => "projects#show"

the request is dispatched to the projects controller’s show action with { :id => “17” } in params.

Similarly, When your Rails application receives an incoming request

GET /projects/manage

it asks the router to match it to a controller action. If the first matching route is

match "/projects/manage" => "projects#manage", :as => 'manage_projects'

the request is dispatched to the projects controller’s manage action without bothering about the id as not given in routes.

But if the first matching route for projects is resource itself for projects, then it will go the show action as it will treat manage as your id just like having /projects/:id and match will get skipped.

So it depends what have you given first i.e. a resource or a match. Priority is important.

This line

match "/projects/manage" => "projects#manage", :as => 'manage_projects'

is most probably added after resources :projects. Move that line above the resources one and you should be good. something like

match "/projects/manage" => "projects#manage", :as => 'manage_projects'
resources :projects

UPDATE:

Routes are ordered. The routes at the top of the file takes precedence. If resources :projects is before match "/projects/manage" => "projects#manage", :as => 'manage_projects', going to /projects/manage goes to the show action of the projects controller because it matches /projects/:id before /projects/manage

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top