The new
action normally doesn't require parameters, since it creates a new resource from scratch.
In my application whenever i create a certain type of resource say a book
i need to provide a template, that is the id of another book
. So my new
route always has a parameter.
I don't know how to represent this fact into routes.rb
file.
Since i don't even know whether it is feasible, just in the case it isn't, then i will create a new_wp, a "new with parameter" action.
I tried to add it to my
resources :books, :only => [:edit, :update, :show, :new] do
member do
get 'new_wp/:template_id', :action => 'new_wp'
end
end
but rake routes say that it isn't quite what i want:
GET /books/:id/new_wp/:template_id(.:format) books#new_wp
that is, it has two params.
Try:
resource ...
get "new/:template_id", :to => "Books#new_wp", :on => :collection
end
# GET /books/new/:template_id(.:format) Books#new_wp
I do this often, the easiest way, I believe is to just adjust the path_names. That way your route names don't get messed up. Let me explain.
Scenario 1 - Standard Rails
Code
resources :books
Output
books GET /books(.:format) books#index
POST /books(.:format) books#create
new_book GET /books/new(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PATCH /books/:id(.:format) books#update
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy
Scenario 2 - Chris Heald Version
Code
resources :books do
get "new/:template_id", to: "books#new_wp", on: :collection
end
# You can also do, same result with clearer intention
# resources :books do
# get ":template_id", to: "books#new_wp", on: :new
# end
Output
GET /books/new/:template_id(.:format) books#new_wp
books GET /books(.:format) books#index
POST /books(.:format) books#create
new_book GET /books/new(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PATCH /books/:id(.:format) books#update
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy
Scenario 3 - My preferred and noted by steakchaser above
Code
resources :books, path_names: {new: 'new/:template_id' }
Output
books GET /books(.:format) books#index
POST /books(.:format) books#create
new_book GET /books/new/:template_id(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PATCH /books/:id(.:format) books#update
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy
You will notice that in scenario 2 you are missing a path name, which means you would want to add an as: :new
which would generate new_new_book
. Fixing this you can change from get ":template_id" ...
to get path: ":template_id"...
which will generate new_book
My preference is scenario 3 if all you want to do is pass arguments for new. If you want to change the action then you would want to consider using scenario 2 but exclude :new
from the resource or in your case don't add :new
to the only:
argument.