views:

631

answers:

1

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?

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
A: 

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
EmFi
Hi EmFi. Fabulous, thanks. I forgot to mention, I wanted each projectpart's ID to be unique within each project, so that every project will have a projectpart with an ID of 1, but none hopefully will have a projectpart with an ID of 132513452345. I've taken your format, removed the :shallow, and split it into two nestings, one from @projects to @solutions inclusive, and the other from @solutions to @images/@documents inclusive. Much appreciated.
steven_noble
Making context sensitive ID's is not built into Rails. I've never used it, but the composite primary keys plugin (http://compositekeys.rubyforge.org/) should be able to help you out here.
EmFi
Cheers. I was going to add a partcount column to the projectparts table and call it via friendly_id, but this looks like a handy alternative.
steven_noble