1

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?

mahemoff
  • 44,526
  • 36
  • 160
  • 222
  • possible duplicate of [Default segment name in rails resources routing](http://stackoverflow.com/questions/182040/default-segment-name-in-rails-resources-routing) – edgerunner Jan 08 '12 at 00:31
  • Didn't see that when searching, but I think this is sufficiently different as it's about retaining the first name and dropping the second, whereas that question is vice-versa. Nested routing being the tricky thing it is, it's a separate enough problem to make a separate question a useful resource. I'll update the title to reflect the difference. – mahemoff Jan 08 '12 at 13:37
  • Confirmed this works in Rails 3.1. If you can answer the question with resources :songs, :path => '', I'll accept it. – mahemoff Jan 08 '12 at 20:11
  • 1
    I got an even better one for you – edgerunner Jan 08 '12 at 21:42

2 Answers2

1

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"}
edgerunner
  • 14,873
  • 2
  • 57
  • 69
  • That actually is a better one :). Thanks. In case anyone else is wondering, the routes declaration here is *not* nested; just declare this as a separate route. – mahemoff Jan 09 '12 at 00:44
0

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

Azolo
  • 4,353
  • 1
  • 23
  • 31