Nested routes don't work for me?

Hi all

I’m quite new to RESTful Rails and tried a bit with a new app, but it
seems I don’t comprehend something yet.

I have the following two models:

class CompactDisc < ActiveRecord::Base
belongs_to :genre
validates_presence_of :genre
end

class Genre < ActiveRecord::Base
has_many :compact_discs
end

In routes.rb I have the following route:

ActionController::Routing::Routes.draw do |map|
map.resources :compact_discs

map.resources :genres do |genre|
genre.resources :compact_discs, :name_prefix => ‘genre_’
end


end

When opening localhost:3000/compact_discs it shows me all CD’s. When
opening localhost:3000/genres/1/compact_discs it still shows me all
CD’s! Shouldn’t it only display the ones that are associated to genre 1
now? Or did I miss something?

I also played with

map.resources :genres, :has_many => :compact_discs

but this didn’t help me neither…

Thanks for help :slight_smile:
Josh

On Aug 15, 9:07 am, Joshua M. [email protected]
wrote:

end
map.resources :genres do |genre|
genre.resources :compact_discs, :name_prefix => ‘genre_’
end


end

Those routes look good…

Thanks for help :slight_smile:
Josh

Posted viahttp://www.ruby-forum.com/.

When you have nested routes, Rails handles almost everything for
you, but you need to adjust your index action to be aware of the
“parent” resource:

def index
if params[:genre]
@genre = Genre.find(params[:genre])
@compact_discs = @genre.compact_discs
else
@compact_discs = CompactDisc.find(:all)
end

continue code here

end

In other words, you want to detect if you’re nested inside a genre,
and in that case, only show the discs for that genre.

There are more elegant ways to do this, too (many people use a
before_filter, etc.)

Does this help at all?

Jeff

REST with Rails: Oct 4, 2008, Austin, TX
http://www.purpleworkshops.com/workshops/rest-and-web-services

Does this help at all?

Jeff

Thanks a lot, Jeff. Can you point me into some “best practices” on how
to make this work? before_filter etc…?

Joshua M. wrote:

Does this help at all?

Jeff

Thanks a lot, Jeff. Can you point me into some “best practices” on how
to make this work? before_filter etc…?

Well, created one myself. You think this is safe and clean/DRY? :slight_smile:

private
def prepare_compact_discs
genre = (params[:genre_id] ? Genre.find(params[:genre_id]) : nil)
@compact_discs = (genre ? genre.compact_discs :
CompactDisc.find(:all))
end

Btw, in your example before you should have used params[:genre_id], not
only params[:genre]. Thanks anyway.

Again, I don’t think there’s a right or wrong necessarily - whatever
you think keeps the code the clearest.

Thanks, interesting ways! :slight_smile: Let’s me feel like a complete newbie again
and again :wink:

On Aug 15, 12:43 pm, Joshua M. [email protected]
wrote:

private
def prepare_compact_discs
genre = (params[:genre_id] ? Genre.find(params[:genre_id]) : nil)
@compact_discs = (genre ? genre.compact_discs :
CompactDisc.find(:all))
end

It’s probably a matter of taste, but I tend to recommend something
like this:

before_filter :find_genre

def index
@compact_discs = @genre ? @genre.compact_discs ||
CompactDisc.find(:all)

end

def find_genre
@genre = Genre.find_by_id(params[:genre_id]) # returns nil if not
foun
end

Some people prefer this:

before_filter :load_for_genre

def index

Find all discs only if we don’t have any yet

@compact_discs ||= CompactDisc.find(:all)
end

def load_for_genre
@compact_discs = Genre.find(params[:genre_id]).compact_discs if
params[:genre_id]
end

Again, I don’t think there’s a right or wrong necessarily - whatever
you think keeps the code the clearest.

Btw, in your example before you should have used params[:genre_id], not
only params[:genre]. Thanks anyway.

Good catch.

Jeff

REST with Rails: Oct 4, 2008, Austin, TX
http://www.purpleworkshops.com/workshops/rest-and-web-services