How to add :format options to a named route in Rails? - ruby-on-rails

I've got a named route called profile and I would like to be able to access it as json. But when I look at my rake routes output I see that the (.:format) is missing. How do I add it to a named route?
user GET /users/:id(.:format) {:action=>"show", :controller=>"users"}
profile /:username {:action=>"show", :controller=>"users"}
Thanks in advance!

Add .format in your path specification, like this:
map.profile '/:profile.:format', :controller => 'users', :action => 'show'
Then you'll end up with:
profile /:profile(.:format) {:action=>"show", :controller=>"users"}

Related

Rails - From RESTFul resource to customized routes

This is a design problem that I am trying to figure out. I will explain what I have right now, and what I would like to have:
1. Actual design
I have a defined a resources :users and by doing so I have defined different actions such as new, create and update in the Users controller. This is working as expected by following urls like users/new , users/:id, etc...
Now I want to go one step forward, and I want to be able to do the following...
2. What am I looking for
I want to be able to have a route like this:
users/overview/profile - This should be equivalent to `users/:id` (show action)
users/overview/network - This should be equivalent to users/:id/network (list of networks for that user)
3. My idea
My first idea was to define something like this:
resource :users do
namespace :overview do
resource :networks
end
end
But this would work for urls like: users/:id/overview/networks and I don't want the user id to be shown in the URL. So my questions are:
1 - How can I deal with users/overview/networks instead of users/:id/overview/networks , assuming that I can get the user id from session.
2 - How can I be able to manage URLs like this: users/overview/profile where actually a profile is just the show method of users/:id Right now I have defined all the actions in the users controller and everything is working fine (new,delete,create,update...) I just don't know how to move into that "namespace" overview/profile
I have tried same thing you tried, and it is returning your desired results only, not sure what is your problem. Posting rake routes result here.
users_overview_networks POST /users/overview/networks(.:format) {:action=>"create", :controller=>"overview/networks"}
new_users_overview_networks GET /users/overview/networks/new(.:format) {:action=>"new", :controller=>"overview/networks"}
edit_users_overview_networks GET /users/overview/networks/edit(.:format) {:action=>"edit", :controller=>"overview/networks"}
GET /users/overview/networks(.:format) {:action=>"show", :controller=>"overview/networks"}
PUT /users/overview/networks(.:format) {:action=>"update", :controller=>"overview/networks"}
DELETE /users/overview/networks(.:format) {:action=>"destroy", :controller=>"overview/networks"}
users POST /users(.:format) {:action=>"create", :controller=>"users"}
new_users GET /users/new(.:format) {:action=>"new", :controller=>"users"}
edit_users GET /users/edit(.:format) {:action=>"edit", :controller=>"users"}
GET /users(.:format) {:action=>"show", :controller=>"users"}
PUT /users(.:format) {:action=>"update", :controller=>"users"}
DELETE /users(.:format) {:action=>"destroy", :controller=>"users"}
scope :path => 'users/overview' do
match ':id/profile', :to => 'users#show'
match ':id/network', :to => 'users#network'
end

Dropping second model name in nested resource route

I'm using slugs for IDs, so wanting URLs like /songs/radiohead/karma-police instead of /artists/radiohead/songs/karma-police.
Slugs can be achieved with:
def to_param
slug
end
But how is there any way to drop the model name - "songs" - from the standard RESTful URL?
You can override the path segment by passing the :path option to your resources call.
resources :songs, path: "songs/:artist_id"
this will generate these routes
songs GET /songs/:artist_id(.:format) {:action=>"index", :controller=>"songs"}
POST /songs/:artist_id(.:format) {:action=>"create", :controller=>"songs"}
new_song GET /songs/:artist_id/new(.:format) {:action=>"new", :controller=>"songs"}
edit_song GET /songs/:artist_id/:id/edit(.:format) {:action=>"edit", :controller=>"songs"}
song GET /songs/:artist_id/:id(.:format) {:action=>"show", :controller=>"songs"}
PUT /songs/:artist_id/:id(.:format) {:action=>"update", :controller=>"songs"}
DELETE /songs/:artist_id/:id(.:format) {:action=>"destroy", :controller=>"songs"}
Put this in your routes.rb and it should work.
match 'artists/:artist_id/:id' => 'songs#show', :as => 'artist_song'
Make sure if you do the :as that the other routes don't take precedence over this one.
Then check out this Routing match reference

Understanding rake routes output

I'm confused by my rake routes output. For an example (trimmed):
profil GET /profil/:id(.:format) {:action=>"show", :controller=>"profil"}
PUT /profil/:id(.:format) {:action=>"update", :controller=>"profil"}
login GET /login(.:format) {:action=>"new", :controller=>"sessions"}
POST /login(.:format) {:action=>"create", :controller=>"sessions"}
logout GET /logout(.:format) {:action=>"destroy", :controller=>"sessions"}
I've always thought:
Line 2: Route can be accessed using profil_path with PUT method.
Line 4: Route can be accessed using login_path with POST method.
Conclusion: Lines with the first column empty (line 2 and 4) would follow the one above it.
However, I've been experimenting with adding parameter to the url. So, I added these codes in my routes.rb:
namespace :admin do
resources :pengguna_bulk, :only => [:new, :create]
resources :pengguna do
collection do
get 'index/:page', :action => :index
end
end
end
New rake routes output (trimmed):
admin_pengguna_bulk_index POST /admin/pengguna_bulk(.:format) {:action=>"create", :controller=>"admin/pengguna_bulk"}
new_admin_pengguna_bulk GET /admin/pengguna_bulk/new(.:format) {:action=>"new", :controller=>"admin/pengguna_bulk"}
GET /admin/pengguna/index/:page(.:format) {:action=>"index", :controller=>"admin/pengguna"}
admin_pengguna_index GET /admin/pengguna(.:format) {:action=>"index", :controller=>"admin/pengguna"}
POST /admin/pengguna(.:format) {:action=>"create", :controller=>"admin/pengguna"}
new_admin_pengguna GET /admin/pengguna/new(.:format) {:action=>"new", :controller=>"admin/pengguna"}
edit_admin_pengguna GET /admin/pengguna/:id/edit(.:format) {:action=>"edit", :controller=>"admin/pengguna"}
admin_pengguna GET /admin/pengguna/:id(.:format) {:action=>"show", :controller=>"admin/pengguna"}
PUT /admin/pengguna/:id(.:format) {:action=>"update", :controller=>"admin/pengguna"}
DELETE /admin/pengguna/:id(.:format) {:action=>"destroy", :controller=>"admin/pengguna"}
My question is, why is the 3rd route looks like it's under the 2nd route? Is it empty because Rails do not know what to name it and I'd have to use get 'index/:page', :action => :index, :as => :page to name it?
So, this means, route with an empty first column doesn't always follow the above path?
I've always thought:
Line 2: Route can be accessed using profil_path with PUT method.
Line 4: Route can be accessed using login_path with POST method.
Conclusion: Lines with the first column empty (line 2 and 4) would
follow the one above it.
Everything's correct except the conclusion. profil_path expands to /profil/:id(.:format). If it is called with method GET it responds to your first route, if its called with method PUT it responds to your second route.
But same doesn't hold true for second set of routes. You don't have any named helper for /admin/pengguna/index/:page(.:format). If you want a named helper, you should define the route like:
get 'index/:page', :action => :index, :as => :what_ever_named_helper_you_want

Routing redirection

I am using Ruby on Rails 3 and I would like to redirect all requests made to a resource (URL) to another resource.
I have the following resources:
<My_app_name>::Application.routes.draw do
resources :users
namespace :users do
resources :user_admins
end
end
What I would like to do is to redirect all requests made to <my_app_name>/users/user_admins/<id> to <my_web_site_name>/users/<id>. How can I do that?
Note: I am using a Single Table Inheritance approach, so that the <id> value will don't change behaviours. That is, the <id> value will be automatically handled from the RoR framework and it will refer to the same resource for both when the URL is <my_app_name>/users/user_admins/<id> or <my_web_site_name>/users/<id>.
You may want to avoid the use of a namespace, and play it like that :
scope "users" do
resources "user_admins", :controller => "users"
end
You'll get those routes :
user_admins GET /users/user_admins(.:format) {:action=>"index", :controller=>"users"}
POST /users/user_admins(.:format) {:action=>"create", :controller=>"users"}
new_user_admin GET /users/user_admins/new(.:format) {:action=>"new", :controller=>"users"}
edit_user_admin GET /users/user_admins/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
user_admin GET /users/user_admins/:id(.:format) {:action=>"show", :controller=>"users"}
PUT /users/user_admins/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /users/user_admins/:id(.:format) {:action=>"destroy", :controller=>"users"}
Try this in your routes.rb:
match 'users/user_admins/:id' => 'users#show'

Rails resourceful routes all point to index action?

I'm runnng Rails 2.3.8.
I set up map.resources :users in my routes.rb file.
When I run rake routes it shows:
users GET /users(.:format) {:action=>"index", :controller=>"users"}
GET /users(.:format) {:action=>"index", :controller=>"users"}
new_user GET /users/new(.:format) {:action=>"index", :controller=>"users"}
edit_user GET /users/:id/edit(.:format) {:action=>"index", :controller=>"users"}
user GET /users/:id(.:format) {:action=>"index", :controller=>"users"}
GET /users/:id(.:format) {:action=>"index", :controller=>"users"}
GET /users/:id(.:format) {:action=>"index", :controller=>"users"}
/:controller/:action/:id
/:controller/:action/:id(.:format)
Sorry about the formatting. But the point is... 1) where are my "PUT", "POST", etc. routes?, 2) Why does everything point to index??
Any help would be much appreciated... Thanks!
UPDATE: Full routes file:
ActionController::Routing::Routes.draw do |map|
map.login "login", :controller => "user_sessions", :action => "new"
map.logout "logout", :controller => "user_sessions", :action => "destroy"
map.resources :users
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
And my users_controller has all the usual new, create, show, edit, update methods...
I think you have one of two problems: either the output from rake routes has been mangled by your terminal screen, or your routes are being overridden by something else you installed, like a rails engine.
The first is easy to check for. it sounds like you have a basic user scaffold setup (and not much else) so fire up script/server, go to http://localhost:3000/users/new. If you see the new user page, you have a terminal display issue, but your routes are fine. If you see the users index page, however, proceed to the next step.
Double-check that the routes file you posted above is indeed the file for your app. This sounds ridiculous, but in some editors it's easy to open the wrong file. In TextMate for example, if you have some gems vendored and open the routes file via command-T, you can have multiple routes.rb files to choose from.
If you're sure you're viewing the correct routes file, the next step is to check your application for any other routes.rb files that may be overriding your main file. From terminal, you can run find ./ -name routes.rb and this will list any other routes files. This is especially likely if you have any rails engines installed.
Let me know how this goes - if you're still having problems, you can zip your application and e-mail it to me, and I'll take a look.

Resources