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.
Related
in my routes.rb file there's just two lines:
match 'movies/orderby/:field' => 'movies#orderby'
and
resources :movies
However, when I run rake routes on my project, I get a funny output, look:
/movies/orderby/:field(.:format) {:controller=>"movies", :action=>"orderby"}
movies GET /movies(.:format) {:action=>"index", :controller=>"movies"}
POST /movies(.:format) {:action=>"create",:controller=>"movies"}
new_movie GET /movies/new(.:format) {:action=>"new", :controller=>"movies"}
edit_movie GET /movies/:id/edit(.:format) {:action=>"edit", :controller=>"movies"}
movie GET /movies/:id(.:format) {:action=>"show", :controller=>"movies"}
PUT /movies/:id(.:format) {:action=>"update",:controller=>"movies"}
DELETE /movies/:id(.:format) {:action=>"destroy", :controller=>"movies"}
You see how the route I've hand-coded is different from the others? (it's the one at the top) Also, Rails has not created a url helper for me....
I get the following error message all the time:
undefined method `movies_orderby' for
...Any ideas????
EDIT: the route works (i.e. if i type a matching URL, it get routed correctly) but I got no url helper method to put in my views!!
When you define routes, the method match will not generate url helpers unless you specify what the name of the helpers should be. So I would recommend that you define it as following:
match 'movies/orderby/:field' => 'movies#orderby', :as => :movies_orderby
resources :movies
When you define the name of the route with :as then you will be able to use it in your views like this if you for example would like to order by title
<%= movies_orderby_path("title") %>
And as a side note, you had correctly defined the match route before the resources route. The other way around could have caused problems.
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.
The following link works in my app:
<%= link_to "invitation", :controller => :invitations, :action => :index %>
To follow restful conventions i changed the link to:
<%= link_to "invitation", index_invitation_path %>
The error that i get is:
undefined local variable or method `index_invitation_path'
Rake routes yields:
invitations GET /invitations(.:format) {:controller=>"invitations", :action=>"index"}
The page name is index.html.erb. The model is invitation.rb. The controller is invitation_controller.rb. Routes has resources :invitations. What am i missing?
Thanks!
Assuming you have the routing correct:
resources :invitations
Then the correct helper for the index action (with the url /invitations.html) is
invitations_path
You can see more information by running rake routes. It will display text like the following:
lists GET /lists(.:format)
{:action=>"index", :controller=>"lists"}
POST /lists(.:format)
{:action=>"create", :controller=>"lists"}
new_list GET /lists/new(.:format)
{:action=>"new", :controller=>"lists"}
edit_list GET /lists/:id/edit(.:format)
{:action=>"edit", :controller=>"lists"}
list GET /lists/:id(.:format)
{:action=>"show", :controller=>"lists"}
PUT /lists/:id(.:format)
{:action=>"update", :controller=>"lists"}
DELETE /lists/:id(.:format)
{:action=>"destroy", :controller=>"lists"}
root /(.:format)
{:controller=>"lists", :action=>"index"}
The above was from a route of my own (for a model called List). The route helper method is shown immediately before the HTTP method. You have to remember to append the _path to each helper method. For example the helper methods I could use are:
list_path(list)
edit_list_path(list)
new_list_path
lists_path
You'll need a route in your routes.rb file that defines a mapping to the invitations controller and the index action.
Typically this is created with a resources call
resources :invitations
Which creates several default routes, which you can see by running rake routes.
For single resources, you can also define it using a match call
match "invitations/:id" => "invitations#index", :as => index_invitation
The rails site has a great resource on routing that provides all the details: Routing from the Outside In
Update: Based on your updated question, your route includes an invitaions (notice the trailing 's') route - nothing with index or invitation. The index_ prefix is generated by the resources call when it creates the default routes for :invitations.
It looks like you've defined a custom get mapping for an invitation. While this may technically work, if you're aim is to support restful routes, use the resources method. And have a read of the Routing guide from rails it's very easy to follow and quite detailed.
type rake routes in your console and look at listing of available routes. Seems to be there is no such route index_invitation_path? maybe it named differently
I think you need "invitations_controller.rb" to contain InvitationsController. Plural.
I've written the admin area of a particular rails app and now I'm ready to set it as own section within the website.
Therefore, it will be /admin
However, I didn't want to have it as /admin within the route itself I wanted to have something less common, so I added a couple of hyphens before and after it.
So the route is /-admin-/ and the namespace is Admin.
After setting this up using :path_prefix => "/-admin-", I have the following code block:
map.namespace "/-admin-/", :name_prefix => "", :path_prefix => "/-admin-" do |admin|
This works for all but shallow routes, instead, in the rake routes output the output is:
new_page GET /-admin-/areas/:area_id/pages/new(.:format) {:action=>"new", :controller=>"admin/pages"}
edit_admin_page GET /admin/pages/:id/edit(.:format) {:action=>"edit", :controller=>"admin/pages"}
admin_page GET /admin/pages/:id(.:format) {:action=>"show", :controller=>"admin/pages"}
PUT /admin/pages/:id(.:format) {:action=>"update", :controller=>"admin/pages"}
DELETE /admin/pages/:id(.:format) {:action=>"destroy", :controller=>"admin/pages"}
areas GET /-admin-/areas(.:format) {:action=>"index", :controller=>"admin/areas"}
POST /-admin-/areas(.:format) {:action=>"create", :controller=>"admin/areas"}
new_area GET /-admin-/areas/new(.:format) {:action=>"new", :controller=>"admin/areas"}
Notice how the shallow-routed routes are prefixed as /admin/ and not as /-admin-/ (as are their parent routes).
Any ideas on how to get around this? Is this a bug in rails or do I need to work around it? I tried adding the :path_prefix to each nested route but it doesn't do anything?
Any ideas?
I'm not sure about your rationale on not using /admin - security through obscurity isn't really security - you should be using something like authlogic to keep out unauthorised users.
Try the following to namespace your admin controllers:
map.namespace :admin, :path_prefix => "-admin-" do |admin|
admin.resources :users
admin.resources :pages
end
A sample generated route:
admin_users GET /-admin-/users(.:format) {:controller=>"admin/users", :action=>"index"}
There is no way to get around this. Turns out that all versions of Rails will break down the URL and its resource names to their lowest points when they're set to shallow. The only solution to this is to set all of your resource routes manually without using map.resources.
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.