Nested resource in Rails3, no route match - ruby-on-rails-3

I have a nested route in rails 3 mapped as
resources :maps do
resource :versions
member do
post 'share'
get 'share'
end
end
but when i try to connect to http://localhost:3000/maps/35/versions/2 i obtains
No route matches "/maps/35/versions/2"
and in rake routes
GET /maps/:map_id/versions/:id(.:format) {:controller=>"versions", :action=>"show"}
or similar (with :id) is missing
other routes with versions works correctly
what's wrong?
EDIT 2:
This is the full rake routes output
maps_public GET /maps/public(.:format) {:controller=>"maps", :action=>"public"}
map_versions POST /maps/:map_id/versions(.:format) {:controller=>"versions", :action=>"create"}
new_map_versions GET /maps/:map_id/versions/new(.:format) {:controller=>"versions", :action=>"new"}
edit_map_versions GET /maps/:map_id/versions/edit(.:format) {:controller=>"versions", :action=>"edit"}
GET /maps/:map_id/versions(.:format) {:controller=>"versions", :action=>"show"}
PUT /maps/:map_id/versions(.:format) {:controller=>"versions", :action=>"update"}
DELETE /maps/:map_id/versions(.:format) {:controller=>"versions", :action=>"destroy"}
share_map POST /maps/:id/share(.:format) {:controller=>"maps", :action=>"share"}
GET /maps/:id/share(.:format) {:controller=>"maps", :action=>"share"}
maps GET /maps(.:format) {:controller=>"maps", :action=>"index"}
POST /maps(.:format) {:controller=>"maps", :action=>"create"}
new_map GET /maps/new(.:format) {:controller=>"maps", :action=>"new"}
edit_map GET /maps/:id/edit(.:format) {:controller=>"maps", :action=>"edit"}
map GET /maps/:id(.:format) {:controller=>"maps", :action=>"show"}
PUT /maps/:id(.:format) {:controller=>"maps", :action=>"update"}
DELETE /maps/:id(.:format) {:controller=>"maps", :action=>"destroy"}

It has to be resources :versions. Note the missing "s" in your case.

In addition to #Femaref's answer, the url you need to access is /maps/35/versions/2. If you want the singular (singleton) resource, then you'd do:
resources :maps do
resource :version
end
And then hit /maps/35/version (doesn't take an id). Which, if you have multiple versions for each map, you probably don't want to do.

Related

new action trying to use show

Here are my routes:
equipment_index GET /equipment(.:format) {:action=>"index", :controller=>"equipment"}
POST /equipment(.:format) {:action=>"create", :controller=>"equipment"}
new_equipment GET /equipment/new(.:format) {:action=>"new", :controller=>"equipment"}
edit_equipment GET /equipment/:id/edit(.:format) {:action=>"edit", :controller=>"equipment"}
equipment GET /equipment/:id(.:format) {:action=>"show", :controller=>"equipment"}
PUT /equipment/:id(.:format) {:action=>"update", :controller=>"equipment"}
DELETE /equipment/:id(.:format) {:action=>"destroy", :controller=>"equipment"}
categories GET /categories(.:format) {:action=>"index", :controller=>"categories"}
POST /categories(.:format) {:action=>"create", :controller=>"categories"}
new_category GET /categories/new(.:format) {:action=>"new", :controller=>"categories"}
edit_category GET /categories/:id/edit(.:format) {:action=>"edit", :controller=>"categories"}
category GET /categories/:id(.:format) {:action=>"show", :controller=>"categories"}
PUT /categories/:id(.:format) {:action=>"update", :controller=>"categories"}
DELETE /categories/:id(.:format) {:action=>"destroy", :controller=>"categories"}
When I go to http://localhost:3000/equipment/new I get the following error:
No route matches {:action=>"show", :controller=>"equipment"}
This is my routes.rb file:
Equipmentmanager::Application.routes.draw do
resources :equipment
resources :categories
end
Everything else are set to the defaults, except that I used nifty:scaffold.
This is in 3.1, but it does it in 3.0 also
I am not sure what I am missing?
So localhost:3000/equipment/new is getting routed with this line:
equipment GET /equipment/:id(.:format) {:action=>"show", :controller=>"equipment"}
As it should be. Since you want it to actually go to the new route you need to call localhost:3000/new_equipment since you have defined that route.
As a bit cleaner syntax if you wanted localhost:3000/new_equipment to route to the new action you could put this line in your routes.rb file (above the resources :equipment line since its more specific):
get "new_equipment" => "equipment#new", :as => "new_equipment"
That line will also define helpers that give you access to new_equipment_path and new_equipment_url

Replacing default routes for a resource in Rails 3

I have a resource defined like so:
resources :referrals, :except => [:show, :edit, :destroy]
and I'd like to replace (not just add a named route) a default route that Rails produces, specifically the one for the update action.
Here is my rake routes:
referrals GET /referrals(.:format) {:action=>"index", :controller=>"referrals"}
POST /referrals(.:format) {:action=>"create", :controller=>"referrals"}
new_referral GET /referrals/new(.:format) {:action=>"new", :controller=>"referrals"}
referral PUT /referrals/:id(.:format) {:action=>"update", :controller=>"referrals"}
share /share(.:format) {:controller=>"referrals", :action=>"new"}
special /special(.:format) {:controller=>"referrals", :action=>"index"}
thanks /thanks(.:format) {:controller=>"pages", :action=>"thanks"}
/:shortlink(.:format) {:controller=>"referrals", :action=>"update"}
/:linktext(.:format) {:controller=>"referrals", :action=>"update"}
root /(.:format) {:controller=>"pages", :action=>"home"}
I'd like either the
/:shortlink(.:format)
or
/:linktext(.:format)
to hit the update action, but not the
/referrals/:id(.:format)
This is to implement a form of non-password "security". When the PUT goes to the update action, I want certain things to happen, but I don't want to require authorization to do this, and I don't want to allow easy guessing of the url based on controller name and simple low-numbered ids.
How can I fully replace the default route given by rails?
resources :referrals, :except => [:show, :edit, :destroy, :update]
match "/whatever_you_want/:variable_here" => "referrals#updated", :as=> the_link, :via=> :put
then in your controller you will access the param with
params[:variable_here]
here the param is whatever you want to compare against in the db, and the path will be create like this:
the_link_path or the_link_url
the :via part will constrain the path per HTTP method so only put request will match
more info here
http://guides.rubyonrails.org/routing.html

Rails 3 app will not match a route even though rake routes shows it

Here is a portion of my routes file:
resource :vendor do post 'modify_account' end
Running rake routes will generate the following line
modify_account_vendor POST /vendor/modify_account(.:format) {:action=>"modify_account", :controller=>"vendors"}
vendor POST /vendor(.:format) {:action=>"create", :controller=>"vendors"}
new_vendor GET /vendor/new(.:format) {:action=>"new", :controller=>"vendors"}
edit_vendor GET /vendor/edit(.:format) {:action=>"edit", :controller=>"vendors"}
GET /vendor(.:format) {:action=>"show", :controller=>"vendors"}
PUT /vendor(.:format) {:action=>"update", :controller=>"vendors"}
DELETE /vendor(.:format) {:action=>"destroy", :controller=>"vendors"}
/vendor(.:format) {:action=>"account", :controller=>"vendors"}
I can load the form and verify the URL is correct in the form's action, but when I submit, the app throws an error:
No route matches "/vendor/modify_account"
Any suggestions as to what I can do to troubleshoot? Firebug verifies that the error page is of type POST.
I had a simular issue with a singleton resource, check that you are passing in the url to the form_tag, we use simple_form and have the following
<%= simple_form_for #enterprise_account, :url => enterprise_account_path do |f| -%>
As it turns out, I believe the issue was with my choice of "action verb" - I should have been using PUT instead of POST. This is my new routes file, and the only thing I had to change was the _url helper method names.
resource :vendor do put 'account', :action => 'modify_account' end

Can't create a url that links to a method in my controller

How do I create a link using link_to, that links to a method in my controller. The link I want to create is something like this:
/meetings/10/contacts/2/send_invite
The send_invite method is in the Contacts controller. I'm unsure what the next step as far as how to setup the routes file. I've tried nesting resources but no luck so far. Also, what is the link to specify in the link_to? I've tried various combinations such as send_invite_path, meeting_contact_send_invite_path, but everything throws an error.
My routes file looks like this:
resources :meetings do
resources :contacts, :only => [:send_invite], :as => :send_invite
end
But then when I try to call send_invite_path, it doesn't work.
expanding on austin's answer. This nesting in config/routes.rb
resources :meetings do
resources :contacts do
member do
post :send_invite
end
end
end
would give you these routes
send_invite_meeting_contact POST /meetings/:meeting_id/contacts/:id/send_invite(.:format) {:action=>"send_invite", :controller=>"contacts"}
meeting_contacts GET /meetings/:meeting_id/contacts(.:format) {:action=>"index", :controller=>"contacts"}
POST /meetings/:meeting_id/contacts(.:format) {:action=>"create", :controller=>"contacts"}
new_meeting_contact GET /meetings/:meeting_id/contacts/new(.:format) {:action=>"new", :controller=>"contacts"}
edit_meeting_contact GET /meetings/:meeting_id/contacts/:id/edit(.:format) {:action=>"edit", :controller=>"contacts"}
meeting_contact GET /meetings/:meeting_id/contacts/:id(.:format) {:action=>"show", :controller=>"contacts"}
PUT /meetings/:meeting_id/contacts/:id(.:format) {:action=>"update", :controller=>"contacts"}
DELETE /meetings/:meeting_id/contacts/:id(.:format) {:action=>"destroy", :controller=>"contacts"}
meetings GET /meetings(.:format) {:action=>"index", :controller=>"meetings"}
POST /meetings(.:format) {:action=>"create", :controller=>"meetings"}
new_meeting GET /meetings/new(.:format) {:action=>"new", :controller=>"meetings"}
edit_meeting GET /meetings/:id/edit(.:format) {:action=>"edit", :controller=>"meetings"}
meeting GET /meetings/:id(.:format) {:action=>"show", :controller=>"meetings"}
PUT /meetings/:id(.:format) {:action=>"update", :controller=>"meetings"}
DELETE /meetings/:id(.:format) {:action=>"destroy", :controller=>"meetings"}
You will need to define the route in your routes.rb file and have setup your routes to be nested. As far as the name goes you can define that in your routes.rb file as well by using :as => "some_name" that will allow you to use link_to some_name_path.
For more info on routes: http://guides.rubyonrails.org/routing.html
Specifically on nested resources: http://guides.rubyonrails.org/routing.html#nested-resources

How to prevent pluralization of a model in Rails?

I have model called Search and a resource named :search. I'd like to name my controller SearchController, rather than SearchesController. But when I initialize an instance of Search, Rails assumes its route has to be "/searches".
Is there anything I can do to stop this?
This should work:
resources :search, :as => :searches
Route urls start with /search, point to search controller and use default naming convention:
searches GET /search(.:format) {:controller=>"search", :action=>"index"}
POST /search(.:format) {:controller=>"search", :action=>"create"}
new_search GET /search/new(.:format) {:controller=>"search", :action=>"new"}
edit_search GET /search/:id/edit(.:format) {:controller=>"search", :action=>"edit"}
search GET /search/:id(.:format) {:controller=>"search", :action=>"show"}
PUT /search/:id(.:format) {:controller=>"search", :action=>"update"}
DELETE /search/:id(.:format) {:controller=>"search", :action=>"destroy"}
The reason for error is that when form has only access to model instance it tries to find a route helper based on pluralized model name. In this case it tried to use searches_path. Things should work if we keep the default route names and change only urls and controller.
Relevant documentation (under "Relying on named routes")