Rails routes error troubleshooting - ruby-on-rails

I'm getting a weird error when I try to link to the show_members action
Routing Error
No route matches "/groups/1/show_members"
#routes.rb
get 'groups/:id/members' => 'groups#show_members'
#groups_controller.rb
def show_members
When I run rake routes I get this:
#rake routes
groups GET /groups(.:format) {:controller=>"groups", :action=>"index"}
groups POST /groups(.:format) {:controller=>"groups", :action=>"create"}
new_group GET /groups/new(.:format) {:controller=>"groups", :action=>"new"}
edit_group GET /groups/:id/edit(.:format) {:controller=>"groups", :action=>"edit"}
group GET /groups/:id(.:format) {:controller=>"groups", :action=>"show"}
group PUT /groups/:id(.:format) {:controller=>"groups", :action=>"update"}
group DELETE /groups/:id(.:format) {:controller=>"groups", :action=>"destroy"}
group_join GET /groups/join(.:format) {:controller=>"groups", :action=>"join"}
group_remove_user PUT /groups/remove_user(.:format){:controller=>"groups", :action=>"remove_user"}
GET /groups/:id/members(.:format){:controller=>"groups", :action=>"show_members"}
UPDATE:
But all I want the show_members action to do is show all the users within that group. I want the user functionality and paths to remain the same. And now the show_members action routes to group, the same as show. In my groups controller, I split the default show group action into three pages, one for the group profile which is show, one for the members in that group which goes to show_members, and one for the news page, which will go to show_news when i get to it.
#groups_controller.rb
def show_members
#group = Group.find(params[:id])
#members = #group.users
#group_admin = User.find(#group.group_admin)
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #group }
end
end
#rake routes
group_join GET /groups/:group_id/join(.:format) {:controller=>"groups", :action=>"join"}
group_remove_user PUT /groups/:group_id/remove_user(.:format) {:controller=>"groups", :action=>"remove_user"}
group GET /groups/:group_id/:id/members(.:format) {:controller=>"groups", :action=>"show_members"}
group_users GET /groups/:group_id/users(.:format) {:controller=>"users", :action=>"index"}
group_user GET /groups/:group_id/users/:id(.:format) {:controller=>"users", :action=>"show"}
I WANT THIS new_user_session GET /users/sign_in(.:format) {:controller=>"devise/sessions", :action=>"new"}
INSTEAD OF THIS new_user_group_session GET /users/groups/:group_id/sign_in(.:format) {:controller=>"devise/sessions", :action=>"new"}
user_group_session POST /users/groups/:group_id/sign_in(.:format) {:controller=>"devise/sessions", :action=>"create"}
destroy_user_group_session GET /users/groups/:group_id/sign_out(.:format) {:controller=>"devise/sessions", :action=>"destroy"}
user_group_password POST /users/groups/:group_id/password(.:format) {:controller=>"devise/passwords", :action=>"create"}
new_user_group_password GET /users/groups/:group_id/password/new(.:format) {:controller=>"devise/passwords", :action=>"new"}
edit_user_group_password GET /users/groups/:group_id/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"}
user_group_password PUT /users/groups/:group_id/password(.:format) {:controller=>"devise/passwords", :action=>"update"}
user_group_registration POST /users/groups/:group_id(.:format) {:controller=>"users/registrations", :action=>"create"}
new_user_group_registration GET /users/groups/:group_id/sign_up(.:format) {:controller=>"users/registrations", :action=>"new"}
edit_user_group_registration GET /users/groups/:group_id/edit(.:format) {:controller=>"users/registrations", :action=>"edit"}
user_group_registration PUT /users/groups/:group_id(.:format) {:controller=>"users/registrations", :action=>"update"}
user_group_registration DELETE /users/groups/:group_id(.:format) {:controller=>"users/registrations", :action=>"destroy"}
user_group_confirmation POST /users/groups/:group_id/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"create"}
new_user_group_confirmation GET /users/groups/:group_id/confirmation/new(.:format) {:controller=>"devise/confirmations", :action=>"new"}
user_group_confirmation GET /users/groups/:group_id/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"show"}
groups GET /groups(.:format) {:controller=>"groups", :action=>"index"}
groups POST /groups(.:format) {:controller=>"groups", :action=>"create"}
new_group GET /groups/new(.:format) {:controller=>"groups", :action=>"new"}
edit_group GET /groups/:id/edit(.:format) {:controller=>"groups", :action=>"edit"}
group GET /groups/:id(.:format) {:controller=>"groups", :action=>"show"}
group PUT /groups/:id(.:format) {:controller=>"groups", :action=>"update"}
group DELETE /groups/:id(.:format) {:controller=>"groups", :action=>"destroy"}
#routes.rb
resources :groups do
get 'join' => 'groups#join'
put 'remove_user' => 'groups#remove_user'
get ':id/members' => 'groups#show_members'
resources :users, :only => [:index, :show]
devise_for :users, :controllers => { :registrations => "users/registrations" }
end

Rails is correct when it says that no route matches /groups/1/show_members - your routes.rb is creating a route for something like /groups/1/members (without the "show_")
You'll need to change routes.rb to look like:
get 'groups/:id/show_members` => 'groups#show_members'

Well the problem is of course you haven't done everything right.
resources :groups do |group|
group.resources :members
end
link_to #member.name, [#group, #member]
Magic.
Now reading the guide would be a very good idea.
http://guides.rubyonrails.org/routing.html

Related

Ruby on Rails Class Variable not being referenced by controller

I have a small web app in Ruby on Rails which lists antique documents and the locations that are referenced by the documents. I can update locations that are already attached to documents, but when trying to create a new document, I get the following error
undefined method `locations' for nil:NilClass
The NilClass occurs in LocationController#new:
def new
#location = #document.locations.new
end
This is called from the view as such
<%= form_for(#location,:url=>new_document_location_path(#document)) do |f| %>
<%= render :partial => "document_locations/form", :locals =>{:f=>f} %>
<%= f.submit "Save",:class=>"span2 btn" %>
<%end%>
So for some reason, the #document class isn't being referenced by the controller. I know the class is accessible to the view and in scope as I am able to view document attributes within the form (eg <%= #document.id %>
So, why is the Controller not able to reference the #document variable? I'm assuming this is down to how I am passing the class variable. Eitherway, I'd be very grateful for some pointers.
This is how the models are defined
class Document < ActiveRecord::Base
has_many :locations, :dependent => :destroy
end
class Location < ActiveRecord::Base
belongs_to :document
end
Here's my routes
Pastpaper::Application.routes.draw do
# added in to test
match '/documents/:id/locations/create' => 'locations#create'
resources :documents do
collection do
match 'permanent_delete/:id' => 'documents#permanently_delete',:as => :permanent_delete
end
match '/authorinfo' => 'documents#authorinfo',:as => :authorinfo
match '/publicationinfo' => 'documents#publicationinfo',:as => :publicationinfo
match '/images' => 'documents#itemimages' ,:as => :itemimages
match '/locations' => 'documents#locations',:as => :locations
match '/itempeople' => 'documents#itempeople' ,:as => :itempeople
match '/people_facts_locations' => 'documents#people_facts_locations',:as => :people_facts_loc
resources :locations, :controller=>"locations"
resources :people ,:controller => "document_people"
resources :document_facts
resource :facts
resources :document_photos
end
resources :home do
collection do
get 'document_search','simple_location_search','date_search','simple_people_search','simple_organisation_search','document_filter'
get 'search_results'
post 'search_results'
end
end
match 'documents/publicationinfo/:id' => 'documents#publicationinfo',:as => :publicationinfo
match 'documents/update/publishinginfo/:id' => 'documents#publishinginfo',:as => :publishinginfo
match 'documents/document_image_remove/:id' => 'documents#remove_image',:as=>"remove_image"
match 'documents/make_primary_image/:id' => 'documents#make_primary_image',:as => :make_primary_image
match 'person_detail/:id' => 'documents#person_detail',:as=>'person_detail'
match 'about', :to=> 'pages#about'
match 'contact', :to => 'pages#contact'
match 'privacy', :to => 'pages#privacy'
match 'terms', :to => 'pages#terms'
match 'help', :to => 'pages#help'
namespace :admin do
resources :document_types
resources :statuses
resources :attribute_types
resources :event_types
resources :users
resources :orders
resources :documents
match 'restore_document/:id' => 'Documents#restore_document', :as => 'restore_document'
match 'report' => 'report#index' ,:as=>:report
match 'report/surname_report' => 'report#surname_report',:as=>:surname_report
match 'report/location_report' => 'report#location_report',:as=>:location_report
end
root :to => 'home#index'
end
And here's the relevant Controllers:
DocumentController
class DocumentsController < ApplicationController
before_filter :prepare_document ,:only => [:locations]
def locations
#locations = #document.locations.order("id asc")
#location = #document.locations.new
end
private
def prepare_document
if params[:id]
#document = Document.find(params[:id], :include => [:document_attributes])
elsif params[:document_id]
#document = Document.find(params[:document_id], :include => [:document_attributes])
end
end
end
LocationsController
class LocationsController < ApplicationController
before_filter :prepare_document
def new
#location = #document.locations.new
end
def create
#location = #document.locations.build
if #location.save
redirect_to document_locations_url(#document)
else
render "new"
end
end
def update
#location = #document.locations.find(params[:id])
if #location.update_attributes(params[:location])
redirect_to document_locations_url(#document)
else
render "edit"
end
end
def prepare_document
if params[:document_id]
if current_user.is_admin?
#document = Document.find(params[:document_id], :include => [:document_attributes])
else
#document = current_user.documents.find(params[:document_id], :include => [:document_attributes])
end
end
end
end
This is how my routes rake out
logout GET /logout(.:format) {:action=>"destroy", :controller=>"sessions"}
login POST /login(.:format) {:action=>"create", :controller=>"sessions"}
forgot_password /forgot_password(.:format) {:action=>"new", :controller=>"password_resets"}
user_home GET /profile(.:format) {:action=>"index", :controller=>"users"}
deactivateaccount /account/deactivate(.:format) {:controller=>"users", :action=>"accountdeactivate"}
changepassword /account/changepassword(.:format) {:controller=>"users", :action=>"changepassword"}
register /user/registration(.:format) {:controller=>"users", :action=>"new"}
users GET /users(.:format) {:action=>"index", :controller=>"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"}
PUT /users/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /users/:id(.:format) {:action=>"destroy", :controller=>"users"}
password_resets GET /password_resets(.:format) {:action=>"index", :controller=>"password_resets"}
POST /password_resets(.:format) {:action=>"create", :controller=>"password_resets"}
new_password_reset GET /password_resets/new(.:format) {:action=>"new", :controller=>"password_resets"}
edit_password_reset GET /password_resets/:id/edit(.:format) {:action=>"edit", :controller=>"password_resets"}
password_reset GET /password_resets/:id(.:format) {:action=>"show", :controller=>"password_resets"}
PUT /password_resets/:id(.:format) {:action=>"update", :controller=>"password_resets"}
DELETE /password_resets/:id(.:format) {:action=>"destroy", :controller=>"password_resets"}
password_reset_path /password_resets/:id/edit(.:format) {:controller=>"password_resets", :action=>"edit"}
/documents/:id/locations/create(.:format) {:controller=>"locations", :action=>"create"}
permanent_delete_documents /documents/permanent_delete/:id(.:format) {:controller=>"documents", :action=>"permanently_delete"}
document_authorinfo /documents/:document_id/authorinfo(.:format) {:controller=>"documents", :action=>"authorinfo"}
document_publicationinfo /documents/:document_id/publicationinfo(.:format) {:controller=>"documents", :action=>"publicationinfo"}
document_itemimages /documents/:document_id/images(.:format) {:controller=>"documents", :action=>"itemimages"}
document_locations /documents/:document_id/locations(.:format) {:controller=>"documents", :action=>"locations"}
document_itempeople /documents/:document_id/itempeople(.:format) {:controller=>"documents", :action=>"itempeople"}
document_people_facts_loc /documents/:document_id/people_facts_locations(.:format) {:controller=>"documents", :action=>"people_facts_locations"}
GET /documents/:document_id/locations(.:format) {:action=>"index", :controller=>"locations"}
POST /documents/:document_id/locations(.:format) {:action=>"create", :controller=>"locations"}
new_document_location GET /documents/:document_id/locations/new(.:format) {:action=>"new", :controller=>"locations"}
edit_document_location GET /documents/:document_id/locations/:id/edit(.:format) {:action=>"edit", :controller=>"locations"}
document_location GET /documents/:document_id/locations/:id(.:format) {:action=>"show", :controller=>"locations"}
PUT /documents/:document_id/locations/:id(.:format) {:action=>"update", :controller=>"locations"}
DELETE /documents/:document_id/locations/:id(.:format) {:action=>"destroy", :controller=>"locations"}
document_people GET /documents/:document_id/people(.:format) {:action=>"index", :controller=>"document_people"}
POST /documents/:document_id/people(.:format) {:action=>"create", :controller=>"document_people"}
new_document_person GET /documents/:document_id/people/new(.:format) {:action=>"new", :controller=>"document_people"}
edit_document_person GET /documents/:document_id/people/:id/edit(.:format) {:action=>"edit", :controller=>"document_people"}
document_person GET /documents/:document_id/people/:id(.:format) {:action=>"show", :controller=>"document_people"}
PUT /documents/:document_id/people/:id(.:format) {:action=>"update", :controller=>"document_people"}
DELETE /documents/:document_id/people/:id(.:format) {:action=>"destroy", :controller=>"document_people"}
document_document_facts GET /documents/:document_id/document_facts(.:format) {:action=>"index", :controller=>"document_facts"}
POST /documents/:document_id/document_facts(.:format) {:action=>"create", :controller=>"document_facts"}
new_document_document_fact GET /documents/:document_id/document_facts/new(.:format) {:action=>"new", :controller=>"document_facts"}
edit_document_document_fact GET /documents/:document_id/document_facts/:id/edit(.:format) {:action=>"edit", :controller=>"document_facts"}
document_document_fact GET /documents/:document_id/document_facts/:id(.:format) {:action=>"show", :controller=>"document_facts"}
PUT /documents/:document_id/document_facts/:id(.:format) {:action=>"update", :controller=>"document_facts"}
DELETE /documents/:document_id/document_facts/:id(.:format) {:action=>"destroy", :controller=>"document_facts"}
document_facts POST /documents/:document_id/facts(.:format) {:action=>"create", :controller=>"facts"}
new_document_facts GET /documents/:document_id/facts/new(.:format) {:action=>"new", :controller=>"facts"}
edit_document_facts GET /documents/:document_id/facts/edit(.:format) {:action=>"edit", :controller=>"facts"}
GET /documents/:document_id/facts(.:format) {:action=>"show", :controller=>"facts"}
PUT /documents/:document_id/facts(.:format) {:action=>"update", :controller=>"facts"}
DELETE /documents/:document_id/facts(.:format) {:action=>"destroy", :controller=>"facts"}
document_document_photos GET /documents/:document_id/document_photos(.:format) {:action=>"index", :controller=>"document_photos"}
POST /documents/:document_id/document_photos(.:format) {:action=>"create", :controller=>"document_photos"}
new_document_document_photo GET /documents/:document_id/document_photos/new(.:format) {:action=>"new", :controller=>"document_photos"}
edit_document_document_photo GET /documents/:document_id/document_photos/:id/edit(.:format) {:action=>"edit", :controller=>"document_photos"}
document_document_photo GET /documents/:document_id/document_photos/:id(.:format) {:action=>"show", :controller=>"document_photos"}
PUT /documents/:document_id/document_photos/:id(.:format) {:action=>"update", :controller=>"document_photos"}
DELETE /documents/:document_id/document_photos/:id(.:format) {:action=>"destroy", :controller=>"document_photos"}
documents GET /documents(.:format) {:action=>"index", :controller=>"documents"}
POST /documents(.:format) {:action=>"create", :controller=>"documents"}
new_document GET /documents/new(.:format) {:action=>"new", :controller=>"documents"}
edit_document GET /documents/:id/edit(.:format) {:action=>"edit", :controller=>"documents"}
document GET /documents/:id(.:format) {:action=>"show", :controller=>"documents"}
PUT /documents/:id(.:format) {:action=>"update", :controller=>"documents"}
DELETE /documents/:id(.:format) {:action=>"destroy", :controller=>"documents"}
paypal_cancel /payments/cancel(.:format) {:controller=>"payments", :action=>"paypal_cancel"}
paypal_return /payments/success(.:format) {:controller=>"payments", :action=>"paypal_return"}
paypal_ipn /payments/ipn(.:format) {:controller=>"payments", :action=>"create"}
document_search_home_index GET /home/document_search(.:format) {:action=>"document_search", :controller=>"home"}
simple_location_search_home_index GET /home/simple_location_search(.:format) {:action=>"simple_location_search", :controller=>"home"}
date_search_home_index GET /home/date_search(.:format) {:action=>"date_search", :controller=>"home"}
simple_people_search_home_index GET /home/simple_people_search(.:format) {:action=>"simple_people_search", :controller=>"home"}
simple_organisation_search_home_index GET /home/simple_organisation_search(.:format) {:action=>"simple_organisation_search", :controller=>"home"}
document_filter_home_index GET /home/document_filter(.:format) {:action=>"document_filter", :controller=>"home"}
search_results_home_index GET /home/search_results(.:format) {:action=>"search_results", :controller=>"home"}
POST /home/search_results(.:format) {:action=>"search_results", :controller=>"home"}
home_index GET /home(.:format) {:action=>"index", :controller=>"home"}
POST /home(.:format) {:action=>"create", :controller=>"home"}
new_home GET /home/new(.:format) {:action=>"new", :controller=>"home"}
edit_home GET /home/:id/edit(.:format) {:action=>"edit", :controller=>"home"}
home GET /home/:id(.:format) {:action=>"show", :controller=>"home"}
PUT /home/:id(.:format) {:action=>"update", :controller=>"home"}
DELETE /home/:id(.:format) {:action=>"destroy", :controller=>"home"}
publicationinfo /documents/publicationinfo/:id(.:format) {:controller=>"documents", :action=>"publicationinfo"}
publishinginfo /documents/update/publishinginfo/:id(.:format) {:controller=>"documents", :action=>"publishinginfo"}
remove_image /documents/document_image_remove/:id(.:format) {:controller=>"documents", :action=>"remove_image"}
make_primary_image /documents/make_primary_image/:id(.:format) {:controller=>"documents", :action=>"make_primary_image"}
person_detail /person_detail/:id(.:format) {:controller=>"documents", :action=>"person_detail"}
about /about(.:format) {:action=>"about", :controller=>"pages"}
contact /contact(.:format) {:action=>"contact", :controller=>"pages"}
privacy /privacy(.:format) {:action=>"privacy", :controller=>"pages"}
terms /terms(.:format) {:action=>"terms", :controller=>"pages"}
help /help(.:format) {:action=>"help", :controller=>"pages"}
def new
#location = #document.locations.build
end
Use build not new. And make your prepare_document private in your controller.
Also
<%= form_for([#document, #location]) do |f| %>
Your url parameter was wrong, you shouldn't post forms to the new action, you should post them to the update action like I showed above.

Rspec namespaced route specs failing even though route exists

I'm using rspec-rails (2.8.1) and rails 3.1.3.
I'm trying to test routes for my Admin::ZonesController. I have verified the route exists in both the browser and by running rake routes. I am not using ActiveRecord (if that matters). When I run the routing spec, it tells me:
ActionController::RoutingError: No route matches "/admin/zones/new"
Here is the test (spec/routing/admin/zones_routing_spec.rb):
require 'spec_helper'
describe "routing to zones" do
it "routes /admin/zones/new to admin/zones#new" do
{ :get => "/admin/zones/new" }.should route_to(
:controller => "admin/zones",
:action => "new"
)
end
end
Here is the controller action whose route I am trying to test (admin/zones#new):
class Admin::ZonesController < Admin::BaseController
before_filter :instantiate_variables
def new
#zone = Zone.new
#campaign = Campaign.new
#rules = [Rule.new]
end
end
Running rake routes gives me this:
POST /hooks/:resource(.:format) {:controller=>"hooks", :action=>"create"}
POST /services/:service/:method(.:format) {:controller=>"services", :action=>"create"}
admin_zones GET /admin/zones(.:format) {:action=>"index", :controller=>"admin/zones"}
POST /admin/zones(.:format) {:action=>"create", :controller=>"admin/zones"}
new_admin_zone GET /admin/zones/new(.:format) {:action=>"new", :controller=>"admin/zones"}
edit_admin_zone GET /admin/zones/:id/edit(.:format) {:action=>"edit", :controller=>"admin/zones"}
admin_zone GET /admin/zones/:id(.:format) {:action=>"show", :controller=>"admin/zones"}
PUT /admin/zones/:id(.:format) {:action=>"update", :controller=>"admin/zones"}
DELETE /admin/zones/:id(.:format) {:action=>"destroy", :controller=>"admin/zones"}
admin_widgets GET /admin/widgets(.:format) {:action=>"index", :controller=>"admin/widgets"}
POST /admin/widgets(.:format) {:action=>"create", :controller=>"admin/widgets"}
new_admin_widget GET /admin/widgets/new(.:format) {:action=>"new", :controller=>"admin/widgets"}
edit_admin_widget GET /admin/widgets/:id/edit(.:format) {:action=>"edit", :controller=>"admin/widgets"}
admin_widget GET /admin/widgets/:id(.:format) {:action=>"show", :controller=>"admin/widgets"}
PUT /admin/widgets/:id(.:format) {:action=>"update", :controller=>"admin/widgets"}
DELETE /admin/widgets/:id(.:format) {:action=>"destroy", :controller=>"admin/widgets"}
zones GET /zones(.:format) {:action=>"index", :controller=>"zones"}
POST /zones(.:format) {:action=>"create", :controller=>"zones"}
new_zone GET /zones/new(.:format) {:action=>"new", :controller=>"zones"}
edit_zone GET /zones/:id/edit(.:format) {:action=>"edit", :controller=>"zones"}
zone GET /zones/:id(.:format) {:action=>"show", :controller=>"zones"}
PUT /zones/:id(.:format) {:action=>"update", :controller=>"zones"}
DELETE /zones/:id(.:format) {:action=>"destroy", :controller=>"zones"}
root / {:controller=>"admin/zones", :action=>"new"}
My routes.rb looks like this:
D2CModularPlatform::Application.routes.draw do
post "/hooks/:resource" => "hooks#create"
post "/services/:service/:method" => "services#create"
namespace :admin do
resources :zones
resources :widgets
end
resources :zones
root :to => "admin/zones#new"
end
My controllers dir looks like this:
controllers
admin
base_controller
widgets_controller
zones_controller
application_controller
hooks_controller
services_controller
zones_controller
My spec/routing dir looks like this:
spec/routing
admin
zones_routing_spec
hooks_routing_spec
services_routing_spec
zones_routing_spec

Sophisticated route and url generation in Rails

I have a group model which has_many article model. And I want to use the following url pattern "{group_id}/{article_id}".
so I wrote these route codes:
resource :groups do
resource :articles
end
match ':group_id/:id(.:format)', :to => 'articles#show', :as => :article
match ':id', :to => 'groups#show', :as => :group
But rails fail to generate correct url for group records and article records. How can I replace the automatic generated article_path and group_path to match my routes?
You're running into problems because you aren't watching out for pluralization. When you define a singular resource route, Rails doesn't treat it as a collection where you would refer to each member with an id. You instead want a plural resources for both groups and articles:
resources :groups do
resources :articles
end
Generates the following routes:
group_articles GET /groups/:group_id/articles(.:format) {:action=>"index", :controller=>"articles"}
POST /groups/:group_id/articles(.:format) {:action=>"create", :controller=>"articles"}
new_group_article GET /groups/:group_id/articles/new(.:format) {:action=>"new", :controller=>"articles"}
edit_group_article GET /groups/:group_id/articles/:id/edit(.:format) {:action=>"edit", :controller=>"articles"}
group_article GET /groups/:group_id/articles/:id(.:format) {:action=>"show", :controller=>"articles"}
PUT /groups/:group_id/articles/:id(.:format) {:action=>"update", :controller=>"articles"}
DELETE /groups/:group_id/articles/:id(.:format) {:action=>"destroy", :controller=>"articles"}
groups GET /groups(.:format) {:action=>"index", :controller=>"groups"}
POST /groups(.:format) {:action=>"create", :controller=>"groups"}
new_group GET /groups/new(.:format) {:action=>"new", :controller=>"groups"}
edit_group GET /groups/:id/edit(.:format) {:action=>"edit", :controller=>"groups"}
group GET /groups/:id(.:format) {:action=>"show", :controller=>"groups"}
PUT /groups/:id(.:format) {:action=>"update", :controller=>"groups"}
DELETE /groups/:id(.:format) {:action=>"destroy", :controller=>"groups"}
If you want to leave off the groups and articles segments you can pass :path => '' to each of the resources definitions, but you are going to have to tread carefully because any request to http://example.com/1/2 will map to an article under groups and be uninformative to end users and bots alike.

Nested routes in Rails with an alias

I have a primary model for my project, Place.rb with a places_controller, and I've currently got it exactly the way I want for the users end of my project. With a nested photos controller, review, etc.
I want now to create a management resource which is mostly just an alias for Places, with its own nested resources, some of them overlapping, some of them new.
I tried creating a new controller for it called Manage, but I'm having a hard time with routes. I'm not quite sure the hangup is, but I figure I'm doing something very wrong. I had little difficulty when I was using Places as controller to a real model and nesting other resources below it.
But for example trying to create a new record for a nested resource doesn't route correctly.
I can get a route path like new_manage_room_path(#place) for a link_to to work fine. But
for creating a New announcement in a form:
form_for manage_room_path(#place) doesn't work correctly given a valid id. I've tried many other combinations supplying the object and :url.
Should I avoid using a separate controller and just create an alias or what is the special routing for this purpose?
map.resources :manage, :collection => { :upcoming => [ :post, :get ], :pending => [ :post, :get ] } do |manage|
manage.resources :rooms
manage.resources :room_rates, :as => :rates
manage.resources :availables
manage.resources :manage_bookings, :as => :bookings
end
map.resources :places do |place|
place.resources :bookings
place.resources :photos, :collection => { :sort => :post }
place.resources :reviews, :only => [ :index, :show ]
end
manage_rooms GET /manage/:manage_id/rooms(.:format) {:controller=>"rooms", :action=>"index"}
POST /manage/:manage_id/rooms(.:format) {:controller=>"rooms", :action=>"create"}
new_manage_room GET /manage/:manage_id/rooms/new(.:format) {:controller=>"rooms", :action=>"new"}
edit_manage_room GET /manage/:manage_id/rooms/:id/edit(.:format) {:controller=>"rooms", :action=>"edit"}
manage_room GET /manage/:manage_id/rooms/:id(.:format) {:controller=>"rooms", :action=>"show"}
PUT /manage/:manage_id/rooms/:id(.:format) {:controller=>"rooms", :action=>"update"}
DELETE /manage/:manage_id/rooms/:id(.:format) {:controller=>"rooms", :action=>"destroy"}
manage_room_rates GET /manage/:manage_id/rates(.:format) {:controller=>"room_rates", :action=>"index"}
POST /manage/:manage_id/rates(.:format) {:controller=>"room_rates", :action=>"create"}
new_manage_room_rate GET /manage/:manage_id/rates/new(.:format) {:controller=>"room_rates", :action=>"new"}
edit_manage_room_rate GET /manage/:manage_id/rates/:id/edit(.:format) {:controller=>"room_rates", :action=>"edit"}
manage_room_rate GET /manage/:manage_id/rates/:id(.:format) {:controller=>"room_rates", :action=>"show"}
PUT /manage/:manage_id/rates/:id(.:format) {:controller=>"room_rates", :action=>"update"}
DELETE /manage/:manage_id/rates/:id(.:format) {:controller=>"room_rates", :action=>"destroy"}
manage_availables GET /manage/:manage_id/availables(.:format) {:controller=>"availables", :action=>"index"}
POST /manage/:manage_id/availables(.:format) {:controller=>"availables", :action=>"create"}
new_manage_available GET /manage/:manage_id/availables/new(.:format) {:controller=>"availables", :action=>"new"}
edit_manage_available GET /manage/:manage_id/availables/:id/edit(.:format) {:controller=>"availables", :action=>"edit"}
manage_available GET /manage/:manage_id/availables/:id(.:format) {:controller=>"availables", :action=>"show"}
PUT /manage/:manage_id/availables/:id(.:format) {:controller=>"availables", :action=>"update"}
DELETE /manage/:manage_id/availables/:id(.:format) {:controller=>"availables", :action=>"destroy"}
manage_manage_bookings GET /manage/:manage_id/bookings(.:format) {:controller=>"manage_bookings", :action=>"index"}
POST /manage/:manage_id/bookings(.:format) {:controller=>"manage_bookings", :action=>"create"}
new_manage_manage_booking GET /manage/:manage_id/bookings/new(.:format) {:controller=>"manage_bookings", :action=>"new"}
edit_manage_manage_booking GET /manage/:manage_id/bookings/:id/edit(.:format) {:controller=>"manage_bookings", :action=>"edit"}
manage_manage_booking GET /manage/:manage_id/bookings/:id(.:format) {:controller=>"manage_bookings", :action=>"show"}
PUT /manage/:manage_id/bookings/:id(.:format) {:controller=>"manage_bookings", :action=>"update"}
DELETE /manage/:manage_id/bookings/:id(.:format) {:controller=>"manage_bookings", :action=>"destroy"}
pending_manage POST /manage/pending(.:format) {:controller=>"manage", :action=>"pending"}
GET /manage/pending(.:format) {:controller=>"manage", :action=>"pending"}
upcoming_manage POST /manage/upcoming(.:format) {:controller=>"manage", :action=>"upcoming"}
GET /manage/upcoming(.:format) {:controller=>"manage", :action=>"upcoming"}
manage_index GET /manage(.:format) {:controller=>"manage", :action=>"index"}
POST /manage(.:format) {:controller=>"manage", :action=>"create"}
new_manage GET /manage/new(.:format) {:controller=>"manage", :action=>"new"}
edit_manage GET /manage/:id/edit(.:format) {:controller=>"manage", :action=>"edit"}
manage GET /manage/:id(.:format) {:controller=>"manage", :action=>"show"}
PUT /manage/:id(.:format) {:controller=>"manage", :action=>"update"}
DELETE /manage/:id(.:format) {:controller=>"manage", :action=>"destroy"}
Try:
<% form_for #new_room, :url => manage_rooms_path(#place) do |f| %>
or maybe it will work this way:
<% form_for manage_rooms_path(#place, #new_room) do |f| %>
#new_room is new instance of Room model, so in controller add:
#new_room = Room.new

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?
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

Resources