Shared Nested Resources

The skinny is that I’m attempting to add “Discussions” as resources
under different resources (“Groups”, “Projects”, for example) and I’ve
simply hit a roadblock (or two).

Discussions are an association between the “discussable” (Group,
Project, etc.) and a “Topic” so:
class Discussion < ActiveRecord::Base
belongs_to :topic
belongs_to :discussable, :polymorphic => true
end

The roadblock comes about in a few places; when wanting to reference a
discussion’s “discussable” for using the resource methods for pathing:
discussion_path(@discussable, @discussion). Here I did a check to see
what discussable ids are present in the params. So that is solved
though not as nice as I’d like.

That managed to get me through the first roadblock but then I realised
that now I’d have to do all sorts of logic elsewhere to determine what
@discussable is and how to treat it (if its a Group or a Project, etc).

I’m hoping that I’m unaware of a way of dealing with this kind of thing
and that hopefully someone here can shed some light on it. However, if
not, I guess I’ve got my work cut out for me. I suppose the solution
would be some sort of formalized way of dealing with polymorphic
resources. I’d have to devote some serious thought to that though.

Any help is appreciated.

Thanks.

I’m hoping that I’m unaware of a way of dealing with this kind of thing
and that hopefully someone here can shed some light on it. However, if
not, I guess I’ve got my work cut out for me. I suppose the solution
would be some sort of formalized way of dealing with polymorphic
resources. I’d have to devote some serious thought to that though.

In the plugin SimplyHelpful there are a number of polymorphic route
methods that will soon make its way into Edge. It allows you to do
polymorphic_url(@discussable) and get group_url(@discussable) if Group
is the class of the @discussable.

In the plugin SimplyHelpful there are a number of polymorphic route
methods that will soon make its way into Edge. It allows you to do
polymorphic_url(@discussable) and get group_url(@discussable) if Group
is the class of the @discussable.

Much appreciated, I’ll be checking that out right about now.

The polymorphic_url methods work great and are more elegant than my
solution. However, there’s one final snag that I’ve run across.
Beacause I’ve got two resource declarations for discussions, I am using
name prefixes to avoid overwriting. Example:

map.resources :projects do |projects|
projects.resources :participants
projects.resources :discussions, :name_prefix => ‘project_’
end

map.resources :groups do |groups|
groups.resources :memberships
groups.resources :discussions, :name_prefix => ‘group_’
end

Since all discussions are handled through my discussions controller and
I can not simply use new_discussion_path(@discussable), I’ve defined the
following as a helper:

def new_discussion_path(discussable)
case discussable.class.to_s
when ‘Project’
project_new_discussion_path(discussable)

  when 'Group'
    group_new_discussion_path(discussable)
end

end

(Forgive my beginner’s knowledge of the language and framework, I am
doing my best to learn them thoroughly).

Looking over the code for SimplyHelpful I didn’t see anything that
addressed this type of scenario. Would you suggest this be best
generalized into a plugin? If so, could you nudge me in a direction?
I’ve never written a plugin for Rails but I am quite interested in doing
so.

Thanks for your time.

Hey,

The problem you’re describing is one of the reasons I created my
resource_fu plugin:

http://agilewebdevelopment.com/plugins/resource_fu

You can see it in use in the caboose sample app:

http://blog.caboo.se/articles/2007/4/15/sample-app-gets-a-quick-bump

The plugin takes the attitude that trying model a polymorphic
relationship (“something has a discussion”) with a monomorphic
controller (a single discussions controller) is a pain - you’re
better off creating different controllers for each polymorph (IMHO).

There’s stuff in the resource_fu to keep things DRY and it “plays
nice” with simply helpful :slight_smile:

HTH,
Trevor