I'm currently wrestling with a problem. My application has Attendees that either belong to PrivateCourses or Bookings. It uses a polymorphic association for this: has_many :attendees, :as => :attendable.
However, in both cases the UI is pretty much identical. So I figured I could set up routes like so:
map.resources :private_courses do | private_course |
private_course.resources :attendees, :name_prefix => 'private_course_'
map.resources :bookings do | booking |
booking.resources :attendees, :name_prefix => 'booking_'
This gives me three options: either reference the attendee in the context of a PrivateCourse private_course_attendees_path(@private_course), in the context of a Booking booking_attendee_path(@booking) or all on its own attendee_path(@attendee). I was thinking I could examine the supplied parameters to figure out what the Attendable should be:
@attendable = Booking.find params[:booking_id]
@attendable = PrivateCourse.find params[:private_course_id]
@attendee = Attendee.find params[:id]
@attendee = @attendable.attendees.find params[:id]
Looks good so far.
But it turns out my view code is turning into a conditional nightmare. Take the "new" form:
form_for :attendee, :url => private_course_new_attendee_path(@attendee.attendable) do | form |
form_for :attendee, :url => booking_new_attendee_path(@attendee.attendable) do | form |
Of course, not only is this ugly but there needs to be code in the controller to set up the new Attendee's Attendable. In which case I should just make the controller look like this:
@attendee = @attendable.attendees.build
render :action => 'new_attendee_for_private_course'
render :action => 'new_attendee_for_booking'
Yet as I went through this, I kept thinking that every single action needs the same conditional logic - actual form definitions aside, there is actually nothing that is shared between the two conditions.
So, my answer, barring a flash of inspiration, is "No, you cannot use the same controller in two places at once".
Now I need to rework my body of code to have two controllers - PrivateCourseAttendees and BookingAttendees that both make use of a set of shared partials, probably in an Attendees folder.