1

我有一个Event模型,我想创建它的两个子类:FixedEventTasksEvent

事件模型具有以下属性:

uid       :string
title     :string
starts_at :datetime
ends_at   :datetime

FixedEvent 继承自 Event 也有这个属性:

all_day   :boolean

TasksEvent 继承自 Event 并具有以下属性:

task_id   :integer
occurrence :integer

(Occurrence 属性是任务的一种特殊表达方式:Do this task two/three/x 次。Occurrence 表示这是该任务的哪一次出现(例如,这是用户第二次执行该任务))

昨天我花了一整天时间阅读有关单表继承和多态关联的信息,但我仍然不能 100% 确定在 Rails 中实现这一点的正确方法是什么。

单表继承在我的数据库中留下了很多空值,因为我最终将拥有一个包含以下内容的表:uid、title、starts_at、ends_at、all_day、task_id、occurrence、type。这种行为是否会使服务器响应变慢,因为 rails 将为每个事件查询获取更多(空)数据?

另一方面,多态关联看起来更像是在为模型添加一些额外的功能,而不是对其进行子类化。它还在数据库中创建更多表(在本例中为三个):

events:
id, uid, title, starts_at, ends_at,
created_at, updated_at,
event_type_id, event_type_type

(如果您想到了什么,建议更好地命名类型)

fixed_events:
id
all_day
created_at
updated_at

tasks_events:
id
task_id
occurrence
created_at
updated_at

这种行为是否会使服务器响应变慢,因为每次我想获取所有 FixedEvent/TasksEvent 属性时,rails 都必须进行多个数据库连接?

另外,如何使用 STI 和/或多态关联创建新的 ActiveRecord 对象?我为多态关联尝试了这样的事情:

def new
  @fixed_event = FixedEvent.new
  @fixed_event.build_event

  respond_to :html
end

然后在 form_for 中:

= f.fields_for :event do |event|
  .field
    = event.label :title
    = event.text_field :title
  .field
    = event.label :starts_at
    = event.datetime_select :starts_at
  .field
    = event.label :ends_at
    = event.datetime_select :ends_at
  .field
    = event.label :description
    = event.text_field :description
  .field
    = event.label :uid
    = event.text_field :uid

我必须添加这两件事FixedEvent并且TasksEvent它起作用了:

attr_accessible :event_attributes
accepts_nested_attributes_for :event

这是正确的方法还是 STI 更好(或任何其他解决方案)?

4

1 回答 1

1

您想使用 STI,因为它很简单,并且比加载关联要快得多。加载一堆空值没什么好担心的,性能方面。另一方面,一旦您的事件表包含数以万计的条目,连接(甚至是预加载)更有可能导致性能问题。

如果选择所有列对您来说成为问题,您始终可以只选择所有列的子集:

FixedEvent.select('foo, bar').all

看来您已经了解 STI,所以我不必在这里教您如何操作。真的很简单——只需创建带有“type”列和 Event 类的“events”表,然后将其子类化。

于 2013-05-23T14:24:51.917 回答