Nicer routes in RESTful Rails...?

Hi all

Recently I updated my whole website to RESTful Rails. Before I had nice hierarchical routes like

music/ => MusicController music/artists => MusicArtistsController music/albums => MusicAlbumsController music/labels => MusicLabelsController

This was quite easy using custom routes. But now, I'm just using

map.resources :music map.resources :music_artists map.resources :music_albums map.resources :music_labels

which causes that I don't have this cool hierarchy in the domain like before, only

music/ => MusicController music_artists => MusicArtistsController music_albums => MusicAlbumsController music_labels => MusicLabelsController

Is there an easy way to gain the hierarchy back? :slight_smile:

Thanks Josh

map.resources :music do |music|   music.resources :artists   music.resources :albums   music.resources :labels end

can be nested deeper, too and map.namespace allows for something like an admin namespace

Thorsten Mueller wrote:

map.resources :music do |music|   music.resources :artists   music.resources :albums   music.resources :labels end

can be nested deeper, too and map.namespace allows for something like an admin namespace

Looks good, but when using

map.resources :music do |music|   music.resources :music_artists end

I will get

music/music_artists

But I'd like to have

music/artists

:slight_smile:

i'm sure, you can fix that... :wink:

Could you be a little more specific? You don't mean that I should rename my controllers, do you?

Joshua Muheim wrote:

Could you be a little more specific? You don't mean that I should rename my controllers, do you?   

That's what I would do.

Jon Garvin wrote:

Joshua Muheim wrote:

Could you be a little more specific? You don't mean that I should rename my controllers, do you?   

That's what I would do.

-- http://www.5valleys.com/ http://www.workingwithrails.com/person/8078

That's OK, but what if I don't only have the model MusicArtist but also DecorationArtist?

You didn’t read the solution well enough. You’re best of renaming your controller to artists_controller.

I guess I slowly get the idea... With RESTful Rails you can only use route structures that are logically tied to the models and their relations, right?

(I have renamed my model MusicArtist to Artist in the meanwhile.)

class Music < ActiveRecord::Base   has_many :artists end

class Artist < ActiveRecord::Base   belongs_to :music end

In this case this will work:

map.resources :music do |music|   map.resources :artists end

But this doesn't really make sense in my case. I want to be able to structure it semantically, my models Music and Artist don't have any relation to each other!

My website has different main parts, e.g. music, info etc. For each of these main parts I have a controller: MusicController, InfoController etc. When accessing

example.com/music

the MusicController delivers me with some common information about what I can find in the sub sections of "music", e.g. a listing of music artists in

example.com/music/artists

So the relation between MusicController (which doesn't even have its own model!) and ArtistsController is only a semantically one, there's no "real" relation between them!

So is it possible somehow to add the prefix "music/" to the routes of Artist?

Ah, well I guess, I should use :path_prefix for this, right? There's no easier, DRYer way to do this? Because at the moment my routes look like this:

map.music 'music/:action/:id' map.resources :artists, :path_prefix => '/music' map.resources :labels, :path_prefix => '/music' map.resources :styles, :path_prefix => '/music'

It would be nicer to have something like

map.path_prefix :music do |prefix|   prefix.resources :artists   prefix.resources :labels   prefix.resources :styles end

Thanks for informations. :slight_smile: Josh

@Joshua -- REST, even in its Rails incarnation, does not have any requirement about the naming of models/controllers or their interaction. A resource, in the REST vernacular, is simply an addressable object that understands how to respond to a particular set of commands. Technically speaking, a resource could be a front for one object (the Rails standard from script/generate scaffold) but you could also have a resource that is composed of many objects (e.g., a blog post with comments could be represented as a single resource) and even one with no models (e.g., the Session from restful_authentication).

In your particular case it really sounds like you want to look into namespacing routes. This would allow you to create a hierarchy of controllers (app/controllers/music, app/controllers/film) and have separate controllers for each 'namespace'... but all of them could be fronts for the same set of models. As Thorsten mentions, this is often done with 'admin', allowing an index with edit links and an edit page only for admins while the rest of the community may see only an index and show.

map.namespace :music do |music|   music.resources :artists   music.resources :albums end

map.namespace :film do |film|   film.resources :artists   film.resources :movies end

=> /music/artists /music/albums

/film/artists /film/movies

etc

HTH, AndyV

Thanks for your explanation, Andy.

I figured it out how to achieve the results that I want on my own:

map.resources :artists,   :name_prefix => 'music_',   :path_prefix => '/music',   :controller => 'music_artists'

But now I tried it with namespace:

map.namespace :music do |music|   map.resources :artists, :name_prefix => '_music' end

But now I'm getting the error "No action responded to artists".

What am I doing wrong?

Thanks again, Josh

You need to do:

  map.namespace :music do |music|     map.resources :artists, :controller => 'music_artists'   end

I suggest you read David Black's eBook on Rails routing, The Rails Way by Obie Fernandez, or read one of the various RESTful routing PDF's out there. It will explain all of this. :slight_smile:

--Jeremy

Thanks for your help! But

  map.namespace :music do |music|     map.resources :artists, :controller => 'music_artists'   end

gives me

Unknown action No action responded to artists

and

  map.namespace :music do |music|     music.resources :artists, :controller => 'music_artists'   end

gives me

NameError in Music/music artistsController#show uninitialized constant Music

Any idea? :wink:

Ah stupid typos on my part. Also, when you namespace, you need to move them into their own directory. So, for example, you'd need to move app/controllers/artists_controller.rb into app/controllers/music/artists_controller.rb.

Then, this should work:

map.namespace :music do |music|   music.resources :artists end

And you should get url's like 'music/artists' with the ability to have something like 'painting/artists' too.

--Jeremy

Cool! Does this work with models, too? Instead of having

music_styles.rb music_artists.rb

I could use

music/styles.rb music/artists.rb

Jeremy McAnally wrote:

You need to do:

  map.namespace :music do |music|     map.resources :artists, :controller => 'music_artists'   end

I suggest you read David Black's eBook on Rails routing, The Rails Way by Obie Fernandez, or read one of the various RESTful routing PDF's out there. It will explain all of this. :slight_smile:

--Jeremy

But now I tried it with namespace: Thanks again, Josh -- Posted via http://www.ruby-forum.com/.

>

-- http://jeremymcanally.com/ http://entp.com

Read my books: Ruby in Practice (Ruby in Practice) My free Ruby e-book (http://humblelittlerubybook.com/)

Or, my blogs: http://mrneighborly.com http://rubyinpractice.com

What is the best way to map example.com/admin/orders/:action to ./app/controllers/admin/orders_controller.rb

I had some problems in production (no idea why it only showed there or how to troubleshoot it), but I finally got it working with the following code:

map.resources :orders, :controller => 'admin/orders', :name_prefix => 'admin_', :path_prefix => 'admin'

What is the impact of this? ie: suppose I wanted a public viewable list orders from example.com/orders/list

Also, for whatever reason, example.com/admin/orders/list still gives me a 404, but without the action it works fine.

Anthony:

http://frozenplague.net/2008/03/16/administration-namespacing/