Nested routes with a 2-way has_many using join table?

I have two classes, InstructionalObject and Assets. They both have_many
of the other, implemented through a join table (so it’s like a habtm
without the habtm).

For the next version of our app, we’re refactoring to RESTful, and i’m
having trouble with my nested resources/routes. I tried this, in
routes.rb:

map.resources :assets do |assets|
assets.resources :instructional_objects
end

map.resources :instructional_objects do |instructional_objects|
instructional_objects.resources :assets
end

thinking that would let me do

instructional_objects/:id/assets

to get all the assets belonging to that instructional_object

and

assets/:id/instructional_objects

for vice-versa.

However, when i go to these urls i get all assets, and all instructional
objects respectively: in other words, these two routes seem to be
equivalent

“instructional_objects/:id/assets” and “assets”

and these two are equivalent:

“assets/:id/instructional_objects” and “instructional_objects”.

To make life more confusing for myself (initially at least) i’m also
using resource_this in my controllers. Looking in the log, it looks
like the right request (i think) is going through:

Processing AssetsController#index (for 127.0.0.1 at 2008-03-12 13:45:56)
[GET]
Session ID: 4ca8db0cc675a9dd71fc0ee96031f6ea
Parameters: {“instructional_object_id”=>“0”, “action”=>“index”,
“controller”=>“assets”}

Can anyone help, please?
max

I understand the need to use has_many :through in both directions, but
does your site actually need to present the data to users in both
directions? Sometimes this can be more of a theoretical need than a
practical one.

At any rate, if you’re “going RESTful” with brand new controllers, the
controllers themselves need some help. They don’t know anything about
the routing that directed the request to them so you’ve got to add
some code.

The main question that you need to answer is whether you ever need to
render an index that’s not scoped. That is, will you ever need to
render a list of assets (all) rather than assets that are associated
to a particular instructional_object? If not then you can simply
modify your index method along these lines:

def index
@instructional_object =
InstructionalObject.find(param[:instructional_object_id])
@assets = @instructional_object.assets
end

On Mar 12, 10:01 am, Max W. [email protected]

The main question that you need to answer is whether you ever need to
render an index that’s not scoped. That is, will you ever need to
render a list of assets (all) rather than assets that are associated
to a particular instructional_object? If not then you can simply
modify your index method along these lines:

def index
@instructional_object =
InstructionalObject.find(param[:instructional_object_id])
@assets = @instructional_object.assets
end

On Mar 12, 10:01 am, Max W. [email protected]

Hi Andreas

Funnily enough, after a discussion with my colleague we decided exactly
that, ie that we never want to see all assets, we always want the ones
belonging to a specified instructional_object.

So, i modified the code like you suggest above, but all on one line:

@assets =
InstructionalObject.find(params[:instructional_object_id]).assets

That works. But now i have a new, weird problem: the ‘new_asset_path’
helper on this page needs to be given an instructional object, so it
knows what it belongs to. So, i modified my code to actually be the
same as you suggest, ie to define @instructional_object and @assets.
And now, when i refresh the page, i get an error saying

“stack level too deep”

and this trace:
/usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/attribute_methods.rb:193:in
method_missing' /usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/attribute_methods.rb:194:in method_missing’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1948:in
to_param' (eval):2:in asset_path’
app/views/assets/index.html.erb:13:in
_run_erb_47app47views47assets47index46html46erb' app/views/assets/index.html.erb:9:in _run_erb_47app47views47assets47index46html46erb’
/usr/bin/mongrel_rails:19:in `load’
/usr/bin/mongrel_rails:19

Just from changing the controller to pass @instructional_object through
as well! I’m totally mystified here…any suggestions?

thanks
max