Shallow nested Rails routing with :as
I want:
Every projectpart to belong to a project.
Every solution to belong to a projectart (and to a project through that projectpart).
Every image to belong to a solution (and to a project and a projectpart through that solution.)
Every document to belong to a solution (and to a project and a projectpart through that solution.)
Every URL to be as short as simple as possible.
Every case of "projectpart" to appear as "part" in every URL. (I couldn't call the model "part" on Heroku.)
Can anyone tell me why this...
ActionController::Routing::Routes.draw do |map|
map.resources :projects, :shallow => true do |project|
project.resources :projectparts do |part|
part.resources :solutions do |solution|
solution.resources :images
solution.resources :documents
end
end
end
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
...is leaving a whole bunch of cases of "projectpart" in my URLs...
steven-nobles-imac-200:drominay steven$ rake routes
(in /Users/steven/Drominay)
projects GET /projects {:controller=>"projects", :action=>"index"}
formatted_projects GET /projects.:format {:controller=>"projects", :action=>"index"}
POST /projects {:controller=>"projects", :action=>"create"}
POST /projects.:format {:controller=>"projects", :action=>"create"}
new_project GET /projects/new {:controller=>"projects", :action=>"new"}
formatted_new_project GET /projects/new.:format {:controller=>"projects", :action=>"new"}
edit_project GET /projects/:id/edit {:controller=>"projects", :action=>"edit"}
formatted_edit_project GET /projects/:id/edit.:format {:controller=>"projects", :action=>"edit"}
project GET /projects/:id {:controller=>"projects", :action=>"show"}
formatted_project GET /projects/:id.:format {:controller=>"projects", :action=>"show"}
PUT /projects/:id {:controller=>"projects", :action=>"update"}
PUT /projects/:id.:format {:controller=>"projects", :action=>"update"}
DELETE /projects/:id {:controller=>"projects", :action=>"destroy"}
DELETE /projects/:id.:format {:controller=>"projects", :action=>"destroy"}
project_projectparts GET /projects/:project_id/projectparts {:controller=>"projectparts", :action=>"index"}
formatted_project_projectparts GET /projects/:project_id/projectparts.:format {:controller=>"projectparts", :action=>"index"}
POST /projects/:project_id/projectparts {:controller=>"projectparts", :action=>"create"}
POST /projects/:project_id/projectparts.:format {:controller=>"projectparts", :action=>"create"}
new_project_projectpart GET /projects/:project_id/projectparts/new {:controller=>"projectparts", :action=>"new"}
formatted_new_project_projectpart GET /projects/:project_id/projectparts/new.:format {:controller=>"projectparts", :action=>"new"}
edit_projectpart GET /projectparts/:id/edit {:controller=>"projectparts", :action=>"edit"}
formatted_edit_projectpart GET /projectparts/:id/edit.:format {:controller=>"projectparts", :action=>"edit"}
projectpart GET /projectparts/:id {:controller=>"projectparts", :action=>"show"}
formatted_projectpart GET /projectparts/:id.:format {:controller=>"projectparts", :action=>"show"}
PUT /projectparts/:id {:controller=>"projectparts", :action=>"update"}
PUT /projectparts/:id.:format {:controller=>"projectparts", :action=>"update"}
DELETE /projectparts/:id {:controller=>"projectparts", :action=>"destroy"}
DELETE /projectparts/:id.:format {:controller=>"projectparts", :action=>"destroy"}
projectpart_solutions GET /projectparts/:projectpart_id/solutions {:controller=>"solutions", :action=>"index"}
formatted_projectpart_solutions GET /projectparts/:projectpart_id/solutions.:format {:controller=>"solutions", :action=>"index"}
POST /projectparts/:projectpart_id/solutions {:controller=>"solutions", :action=>"create"}
POST /projectparts/:projectpart_id/solutions.:format {:controller=>"solutions", :action=>"create"}
new_projectpart_solution GET /projectparts/:projectpart_id/solutions/new {:controller=>"solutions", :action=>"new"}
formatted_new_projectpart_solution GET /projectparts/:projectpart_id/solutions/new.:format {:controller=>"solutions", :action=>"new"}
edit_solution GET /solutions/:id/edit {:controller=>"solutions", :action=>"edit"}
formatted_edit_solution GET /solutions/:id/edit.:format {:controller=>"solutions", :action=>"edit"}
solution GET /solutions/:id {:controller=>"solutions", :action=>"show"}
formatted_solution GET /solutions/:id.:format {:controller=>"solutions", :action=>"show"}
PUT /solutions/:id {:controller=>"solutions", :action=>"update"}
PUT /solutions/:id.:format {:controller=>"solutions", :action=>"update"}
DELETE /solutions/:id {:controller=>"solutions", :action=>"destroy"}
DELETE /solutions/:id.:format {:controller=>"solutions", :action=>"destroy"}
solution_images GET /solutions/:solution_id/images {:controller=>"images", :action=>"index"}
formatted_solution_images GET /solutions/:solution_id/images.:format {:controller=>"images", :action=>"index"}
POST /solutions/:solution_id/images {:controller=>"images", :action=>"create"}
POST /solutions/:solution_id/images.:format {:controller=>"images", :action=>"create"}
new_solution_image GET /solutions/:solution_id/images/new {:controller=>"images", :action=>"new"}
formatted_new_solution_image GET /solutions/:solution_id/images/new.:format {:controller=>"images", :action=>"new"}
edit_image GET /images/:id/edit {:controller=>"images", :action=>"edit"}
formatted_edit_image GET /images/:id/edit.:format {:controller=>"images", :action=>"edit"}
image GET /images/:id {:controller=>"images", :action=>"show"}
formatted_image GET /images/:id.:format {:controller=>"images", :action=>"show"}
PUT /images/:id {:controller=>"images", :action=>"update"}
PUT /images/:id.:format {:controller=>"images", :action=>"update"}
DELETE /images/:id {:controller=>"images", :action=>"destroy"}
DELETE /images/:id.:format {:controller=>"images", :action=>"destroy"}
solution_documents GET /solutions/:solution_id/documents {:controller=>"documents", :action=>"index"}
formatted_solution_documents GET /solutions/:solution_id/documents.:format {:controller=>"documents", :action=>"index"}
POST /solutions/:solution_id/documents {:controller=>"documents", :action=>"create"}
POST /solutions/:solution_id/documents.:format {:controller=>"documents", :action=>"create"}
new_solution_document GET /solutions/:solution_id/documents/new {:controller=>"documents", :action=>"new"}
formatted_new_solution_document GET /solutions/:solution_id/documents/new.:format {:controller=>"documents", :action=>"new"}
edit_document GET /documents/:id/edit {:controller=>"documents", :action=>"edit"}
formatted_edit_document GET /documents/:id/edit.:format {:controller=>"documents", :action=>"edit"}
document GET /documents/:id {:controller=>"documents", :action=>"show"}
formatted_document GET /documents/:id.:format {:controller=>"documents", :action=>"show"}
PUT /documents/:id {:controller=>"documents", :action=>"update"}
PUT /documents/:id.:format {:controller=>"documents", :action=>"update"}
DELETE /documents/:id {:controller=>"documents", :action=>"destroy"}
DELETE /documents/:id.:format {:controller=>"documents", :action=>"destroy"}
/:controller/:action/:id
/:controller/:action/:id.:format
...and yet is not generating basic URL helpers, like this?开发者_Go百科
undefined method `project_projectpart_path' for #<ActionView::Base:0x3438ffc> (ActionView::TemplateError)
BTW, everything except changing "projectpart" to "part" in every URL was working fine with this more verbose syntax:
ActionController::Routing::Routes.draw do |map|
map.resources :projects, :has_many => :projectparts
map.resources :projects, :has_many => :solutions
map.resources :projects, :has_many => :images
map.resources :projects, :has_many => :documents
map.resources :projectparts, :has_many => :solutions
map.resources :projectparts, :has_many => :images
map.resources :projectparts, :has_many => :documents
map.resources :solutions, :has_many => :images
map.resources :solutions, :has_many => :documents
map.resources :images
map.resources :documents
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
The answer to your question about route generation is :shallow => true
Providing the shallow option will create longer routes for collection methods of the inner resource(s), while providing shallow routes for member methods of those nested resource(s). Take a closer look at the routes created and you'll see this.
Essentially routes that need an id (edit,update,show,destroy) will the short one containing only the inner most resource . Routes that don't need an id(index,new) will be slightly longer, containing the immediate parent.
You don't need project_projectpart_path
because the project in project_projectpart
can be implied from the project part. Instead just use projectpart_path
for existing project parts.
Your second example provides those missing routes because it never gives the shallow option.
Changing 'projectpart' to 'part' in urls is as simple as adding the :as option in it's definition. Sorry it won't work with the shorthand :has_many version
map.resources :projects, :shallow => true do |project|
project.resources :projectparts, :as => "part" do |part|
part.resources :solutions do |solution|
solution.resources :images
solution.resources :documents
end
end
end
精彩评论