多态关联的模型和控制器设计方法

时间:2010-10-21 17:32:48

标签: ruby-on-rails architecture polymorphism polymorphic-associations

下面我概述了多态关联的结构。

在VacationsController中,我将一些评论内联描述我当前的问题。但是,我想发布这个,看看我的整个方法是否有点偏离。你可以在business_vacations_controller和staff_vacations_controller中看到我必须为模型和控制器制作'getters',以便我可以在vacations_model中访问它们,这样我就知道我正在处理哪种类型的对象。虽然它有效,但它开始有点可疑了。

对于我想要完成的事情,是否有更好的“最佳实践”?

模型

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

控制器

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

1 个答案:

答案 0 :(得分:0)

在VacationsController中跳过它以使其了解上下文感觉好像很多。是否有一个原因是StaffVacationsController和BusinessVacationsController不能各自都有#create动作,并且视图将提交给适当的视图?这些操作已经知道模型上下文,并且能够在之后重定向到相应的URL。