views:

31

answers:

1

Below I have outlined the structure of a polymorphic association.

In VacationsController I put some comments inline describing my current issue. However, I wanted to post this to see if my whole approach here is a little off. You can see in business_vacations_controller and staff_vacations_controller that I've had to make 'getters' for the model and controller so that I can access them from within vacations_model so I know which type of object I'm dealing with. Although it works, it's starting to feel a little questionable.

Is there a better 'best practice' for what I'm trying to accomplish?

models

vacation.rb

 class Vacation < ActiveRecord::Base
   belongs_to :vacationable, :polymorphic => true
 end

business.rb

 class Business < ActiveRecord::Base
   has_many :vacations, :as => :vacationable
 end

staff.rb

 class Staff < ActiveRecord::Base
   has_many :vacations, :as => :vacationable
 end

business_vacation.rb

 class BusinessVacation < Vacation
 end

staff_vacation.rb

 class StaffVacation < Vacation
 end

controllers

business_vacations_controller.rb

 class BusinessVacationsController < VacationsController

   private

     def controller_str
       "business_schedules"
     end

     def my_model
       BusinessVacation
     end

     def my_model_str
       "business_vacation"
     end

 end

staff_vacations_controller.rb

 class StaffVacationsController < VacationsController

   private

     def controller_str
       "staff_schedules"
     end

     def my_model
       StaffVacation
     end

     def my_model_str
       "staff_vacation"
     end

 end

vacations_controller.rb

 class VacationsController < ApplicationController

   def create
     # Build the vacation object with either an instance of BusinessVacation or StaffVacation

     vacation = @class.new(params[my_model_str])

     # Now here's the current issue -- I want to save the object on the association. So if it's a 'BusinessVacation' object I want to save something like:

     business = Business.find(vacation.vacationable_id)
     business.vacations.build
     business.save

     # But if it's a 'StaffVacation' object I want to save something like:

     staff = Staff.find(vacation.vacationable_id)
     staff.vacations.build
     staff.save

     # I could do an 'if' statement, but I don't really like that idea. Is there a better way?

     respond_to do |format|
       format.html { redirect_to :controller => controller_str, :action => "index", :id => vacation.vacationable_id }
     end

   end

   private
     def select_class
       @class = Kernel.const_get(params[:class])
     end
 end
A: 

It feels like a lot of hoops to jump through in the VacationsController to make it aware of the context. Is there a reason that the StaffVacationsController and BusinessVacationsController couldn't each have a #create action and the views would submit to whichever is appropriate? These actions would already know the model context and be able to redirect to the appropriate url afterward.

njorden
Yes, maybe that's the best solution. There's a lot of shared code that's not shown, that's why I had it in the same controller, but maybe it's to the point where I should explore separating them out.
99miles
I was wondering if there may be some shared code motivating that... a bit tough to call without the details, but maybe some of the shared logic would go into the Vacation model and/or a module that's included in the controllers?
njorden