With the following routes:
resources :locations do
resources :newsitems
resource :weather
get 'weather'
end
I don't have a named route for the get action on weather:
location_weather POST /locations/:location_id/weather(.:format) {:action=>"create", :controller=>"weathers"}
new_location_weather GET /locations/:location_id/weather/new(.:format) {:action=>"new", :controller=>"weathers"}
edit_location_weather GET /locations/:location_id/weather/edit(.:format) {:action=>"edit", :controller=>"weathers"}
GET /locations/:location_id/weather(.:format) {:action=>"show", :controller=>"weathers"}
PUT /locations/:location_id/weather(.:format) {:action=>"update", :controller=>"weathers"}
DELETE /locations/:location_id/weather(.:format) {:action=>"destroy", :controller=>"weathers"}
What do I have wrong here? I put the weather in there as both get and resource, but I really want to just have it as an action on my locations controller, as its not actually a separate resource. Any ideas what I'm doing wrong?
If weather truly is not a separate resource then you might not want to use it in the URL and just call locations/:id to retrieve the weather for that location. However, if you are doing other things with locations - as I suspect you are - you should probably go ahead and create a resource for weather. It doesn't need to have anything in it other than the show method, but it's good to have just for inventory purposes and to be RESTful.
Try the following. I think it will provide you what you are looking for:
resources :locations do
matches "weather" => "weather#show"
end
Just delete the 'resource :weather' and you'll get your location_weather route. If all it is is a custom action on the Locations controller that will handle it.
Related
I know this is a newbie question, but I haven't seen an explanation and I'd like one.
What exactly does it mean when Rails issues a routing error like this:
Routing Error
No route matches {:action=>"show", :controller=>"library_imports", :library_id=>#<Library id: 1, ...
What puzzles me is that the message itself shows that my request is being routed to the show action of the library_imports controller. How does that happen if the request URL didn't match any routes?
For the sake of completeness, the URL I'm hitting that results in this error is:
http://localhost:3000/libraries/2/library_imports
which should map to the "index" action, not "show".
The relevant part of config/routes.rb is:
Import::Application.routes.draw do
resources :libraries do
resources :library_imports
end
And the pertinent portion of rake routes output is:
library_library_imports GET /libraries/:library_id/library_imports(.:format) {:action=>"index", :controller=>"library_imports"}
POST /libraries/:library_id/library_imports(.:format) {:action=>"create", :controller=>"library_imports"}
new_library_library_import GET /libraries/:library_id/library_imports/new(.:format) {:action=>"new", :controller=>"library_imports"}
edit_library_library_import GET /libraries/:library_id/library_imports/:id/edit(.:format) {:action=>"edit", :controller=>"library_imports"}
library_library_import GET /libraries/:library_id/library_imports/:id(.:format) {:action=>"show", :controller=>"library_imports"}
PUT /libraries/:library_id/library_imports/:id(.:format) {:action=>"update", :controller=>"library_imports"}
DELETE /libraries/:library_id/library_imports/:id(.:format) {:action=>"destroy", :controller=>"library_imports"}
The error message is misleading for what it doesn't say, rather than what it says. There is indeed no route that can be constructed from :controller => :library_imports, :action => :show, :library_id => #library, because that hash omits the required :id parameter.
It might be less confusing if there were some hint, like (did you leave out a required parameter?).
It's also useful to note that this error is generated (I believe) in the url_for helper, not in the dispatcher. So the request is not actually being routed at all.
I have a simple rails application in which I'm trying to add a very simple type of record ("client_types") to a database.
I have a route in routes.rb which reads:
resources :client_types
And as I understand it, should be a proxy to all of the conventional routes for my client_types resource.
So when I browse to the following URL http://localhost:3000/client_types/new, I get the following routing error at runtime:
No route matches {:action=>"show", :controller=>"client_types"}
Notice the action in question here is show, not new (and I have a method for both of these in my controller).
So... I added the following route below the resources route above, and viola, it works:
match 'client_types/new' => 'client_types#new', :as => :client_type
So what am I missing? My assumption was that resources :client_types in my routing file would have added a route matching the one I explicitly added later.
rake routes reveals the following:
client_types GET /client_types(.:format) {:action=>"index", :controller=>"client_types"}
POST /client_types(.:format) {:action=>"create", :controller=>"client_types"}
new_client_type GET /client_types/new(.:format) {:action=>"new", :controller=>"client_types"}
edit_client_type GET /client_types/:id/edit(.:format) {:action=>"edit", :controller=>"client_types"}
client_type GET /client_types/:id(.:format) {:action=>"show", :controller=>"client_types"}
PUT /client_types/:id(.:format) {:action=>"update", :controller=>"client_types"}
DELETE /client_types/:id(.:format) {:action=>"destroy", :controller=>"client_types"}
client_type /client_types/new(.:format) {:controller=>"client_types", :action=>"new"}
This is now working. I had an issue in one of my views and this error message was a red herring.
For this route:
resources :projects do
member do
resources :stakeholders
end
end
The generated routes are:
projects_stakeholders GET /projects/projects/:id/stakeholders(.:format) {:action=>"index", :controller=>"projects/stakeholders"}
POST /projects/projects/:id/stakeholders(.:format) {:action=>"create", :controller=>"projects/stakeholders"}
new_projects_stakeholder GET /projects/projects/:id/stakeholders/new(.:format) {:action=>"new", :controller=>"projects/stakeholders"}
edit_projects_stakeholder GET /projects/projects/:id/stakeholders/:id/edit(.:format) {:action=>"edit", :controller=>"projects/stakeholders"}
projects_stakeholder GET /projects/projects/:id/stakeholders/:id(.:format) {:action=>"show", :controller=>"projects/stakeholders"}
As these routes have two times a :id parameter, if I have, for instance the URL 'projects/4/stakeholders/11'
In my log file I see this:
Parameters: {"id"=>"11"}
How can I then access my project_id from inside my controller?
Thanks!!!
You don't need the member do block around it. Just do this, and you should start seeing a project_id in your params:
resources :projects do
resources :stakeholders
end
I want to have a namespaced controller called 'portal'.
in this will be nested resources such as companies and products.
I'd like routes like :
/portal/:company_id/product/:id to work
I can get
/portal/company/:company_id/product/:id to work but would like to eliminate the 'company' in the url
Hope that is clear. Please keep in mind that I need the namespaced module portal to exist.
I think you could use scope to achieve what you want. Perhaps like this:
namespace "portal" do
scope ":company_id" do
resources :products
end
end
That will generate the following routes:
portal_products GET /portal/:company_id/products(.:format) {:action=>"index", :controller=>"portal/products"}
POST /portal/:company_id/products(.:format) {:action=>"create", :controller=>"portal/products"}
new_portal_product GET /portal/:company_id/products/new(.:format) {:action=>"new", :controller=>"portal/products"}
edit_portal_product GET /portal/:company_id/products/:id/edit(.:format) {:action=>"edit", :controller=>"portal/products"}
portal_product GET /portal/:company_id/products/:id(.:format) {:action=>"show", :controller=>"portal/products"}
PUT /portal/:company_id/products/:id(.:format) {:action=>"update", :controller=>"portal/products"}
DELETE /portal/:company_id/products/:id(.:format) {:action=>"destroy", :controller=>"portal/products"}
Edit: Accidentally used resource instead of resources. Fixed now.
You can customize the routes to nearly whatever you want if you spell them out directly, like this:
match '/portal/:company_id/product/:id', :to => 'companies_products#show'
The :to part specifies the controller and action to use, something that should match what you have in your routes now. If you're not sure what that is, rake routes will tell you its specific interpretation.
I was reading Simply Rails by Patrick Lenz... maybe I missed something, it seems that whenever we put
map.resources :stories
in routes.rb
then immediately, the controller will have special convention and now Story is a RESTful resource? Maybe the author used the word resource but didn't mention that it is RESTful but they are the same thing?
Having that in routes means that you automatically get some standard routes that help you build a restful application. For example:
new_story GET /story/new(.:format) {:action=>"new", :controller=>"stories"}
edit_story GET /story/edit(.:format) {:action=>"edit", :controller=>"stories"}
story GET /story(.:format) {:action=>"show", :controller=>"stories"}
PUT /story(.:format) {:action=>"update", :controller=>"stories"}
DELETE /story(.:format) {:action=>"destroy", :controller=>"stories"}
POST /story(.:format) {:action=>"create", :controller=>"stories"}
Just having this one line in your routes file, gives you all these paths to use. You just have to make sure you provide the right functionality in new, edit, show, update, destroy and create actions of your stories controller and you will have a restful design.
In order to see what is available route-wise, you can go to your application folder and give the command:
rake routes
This is going to output all the paths available to you, based on what you have entered in your routes file.
BUT!!! If you have other actions in your controller they will NOT be found unless you introduce additional routes ABOVE that .resources line!
So if you have an action called turn_page in the stories controller you need to include a map.connect line before the map.resources line - as in this snippet:
map.connect 'stories/turn_page', :controller => 'stories', :action => 'turn_page'
map.resources :stories
Hope that helps someone! I got stuck for hours working on this one as all the examples are EITHER "regular" routes OR the REST set defined via the .resources statement!
Yes. Once you add that to your routes your Story controller will respond to the common REST verbs in the expected ways.