Rails中的多个模型具有共享接口

时间:2010-03-19 19:02:05

标签: ruby-on-rails models modeling

我不确定Rails中特定情况的最佳结构。我们有几种类型的研讨会。无论车间类型如何,车间的管理都是相同的,因此车间的数据只有一个模型。我们收集参与者对研讨会的反馈意见,每种类型的研讨会的问卷都不同。我想从车间模型中获取有关车间的反馈,但相关模型的类别将取决于车间的类型。如果我在Rails以外的其他方面做这个,我会为WorkshopFeedback设置一个抽象类,然后为每种类型的工作室设置子类:WorkshopFeedbackOne,WorkshopFeedbackTwo,WorkshopFeedbackThree。我不确定如何使用Rails最好地处理这个问题。

我目前有:

class Workshop < ActiveRecord::Base
  has_many :workshop_feedbacks
end

class Feedback < ActiveRecord::Base
  belongs_to :workshop
  has_many :feedback_ones
  has_many :feedback_twos
  has_many :feedback_threes
end

class FeedbackOne < ActiveRecord::Base
  belongs_to :feedback
end

class FeedbackTwo < ActiveRecord::Base
  belongs_to :feedback
end

class FeedbackThree < ActiveRecord::Base
  belongs_to :feedback
end

这似乎不是访问研讨会模型反馈的最简洁方法,因为访问正确的反馈将需要逻辑调查Workshop类型,然后选择,例如@ workshop.feedback.feedback_one。

有没有更好的方法来处理这种情况?使用多态关联进行反馈会更好吗?或者也许使用Module或Mixin作为共享反馈界面?

注意:我在这里避免使用单表继承,因为FeedbackOne,FeedbackTwo,FeedbackThree模型不共享很多常见数据,因此我最终会得到一个带有STI的大型稀疏表。

2 个答案:

答案 0 :(得分:1)

我认为最好的解决方案是创建一个抽象类Workshop,以及3个子类Workshop1,Workshop2和Workshop3。

因此,每个人都会有一套反馈,反馈1到Workshop1,反馈2到Workshop2,......

您可以按如下方式更改子类中的声明:

class Workshop1 < Workshop
  has_many :feedbacks, :class_name => "Feedback1"
end

class Feedback1 < ActiveRecord::Base
  belongs_to :workshop, :class_name => "Workshop1"
end

在您的应用程序中可以使用workshop.feedbacks和feedback.workshop,无论讲习班或反馈的实例属于哪个类。

编辑:您有三种类型的研讨会,其中包含相同的信息,但每个研讨会都有一种特定的反馈。所以最好使用STI for Workshop,而不是反馈。

答案 1 :(得分:0)

您可以对模型进行子类化,如下所示:

class Workshop < ActiveRecord::Base
  has_many :feedback_ones
  has_many :feedback_twos
  has_many :feedback_threes
  #has_many :feedbacks # This MIGHT work, but is untested.  I'm not at a dev setup to try.
end

class Feedback < ActiveRecord::Base
  belongs_to :workshop
  has_many :feedback_ones
  has_many :feedback_twos
  has_many :feedback_threes
end

class FeedbackOne < Feedback
  belongs_to :feedback
end

class FeedbackTwo < Feedback
  belongs_to :feedback
end

class FeedbackThree < Feedback
  belongs_to :feedback
end

这可能是一个更好的解决方案,而且更清洁。您的Feedback表需要有一个type列,它用于将一个表用于多个类。 This blog postSingle Table Inheritance的概念进行了很好的基本介绍。