Can you use the same controller in two places at once?

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_'endmap.resources :bookings do | booking |  booking.resources :attendees, :name_prefix => 'booking_'endmap.resources :attendees

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:

if !params[:booking_id].blank?  @attendable = Booking.find params[:booking_id]elsif !params[:private_course_id].blank?   @attendable = PrivateCourse.find params[:private_course_id]endif @attendable.blank?   @attendee = Attendee.find params[:id]else  @attendee = @attendable.attendees.find params[:id]  end

Looks good so far.

But it turns out my view code is turning into a conditional nightmare. Take the “new” form:

if @attendee.attendable.is_a?(PrivateCourse)  form_for :attendee, :url => private_course_new_attendee_path(@attendee.attendable) do | form |   ...  endelse  form_for :attendee, :url => booking_new_attendee_path(@attendee.attendable) do | form |    ...  endend

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.buildif @attendable.is_a?(PrivateCourse)  render :action => 'new_attendee_for_private_course'else  render :action => 'new_attendee_for_booking'end

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.

This entry was posted on Monday, April 23rd, 2007 at 11:37 am and is filed under Designing Great Software, Ruby on Rails and Software Development. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

2 Responses to “Can you use the same controller in two places at once?”

  1. Ian Says:

    We’ve been wresting with similar issues.

    Check out resources_controller at http://plugins.ardes.com

  2. Baz Says:

    Cheers Ian,

    That looks useful (although it could do with an overview page!)

Leave a Reply