为健身房的发生和时间表之间的建模关系 class

Modeling relation between occurence and schedule for a gym class

我正在尝试对 class 的出现与其时间表之间的关系进行建模。这是我的:

class Schedule < ActiveRecord::Base
  # Has attributes like 
  #  :starts_at (time only, no date)
  #  :repeats_on (weekday name represented as integer)
  #  :type (the type of exercise that will be taught, say Spin, Kickboxing)
  #  :duration
  has_many :occurrences
end  

class Teacher < ActiveRecord::Base
  has_many :occurrences
end

class Occurrence < ActiveRecord::Base
  belongs_to :teacher
  belongs_to :schedule
  # Has attribute
  #  :occurs_on (date only, no time, time comes from schedule reference)
end

现在,如果我对 "schedule" 进行更改(假设我将星期三旋转 class 的 starts_at 从 4:30 下午更改为 5:00 pm),这将影响所有过去发生的 "belonged to" 这个 "schedule"。为了避免这种情况,我似乎需要这样做:每当用户编辑 "schedule" 时,将旧计划标记为不活动,然后创建新计划。这样,只有新出现的事件会指向这个新的时间表,过去的事件不会受到影响。

这是对这种关系建模的正确方法吗?

您需要稍微规范化 Schedule 和 Occurrence 之间的关系,对 Schedule 的编辑不会影响 Occurrence 的未来实例。

现在,您的 Occurrence 从 Schedule 获取其开始时间和结束时间,并且您在 Schedule 和 Occurrence 之间具有一对一的关系,因此更改 Schedule 会更改所有 Occurrences。

您应该将 Schedule 视为 Occurrence 的模板,并允许 Occurrence 维护自己的开始时间和结束时间字段。这两个实体可以具有相同的关系,但是当您查询开始时间时,您查询的是 Occurrence 而不是 Schedule。时间表仅用于提供 "suggested" 开始和结束时间。

非规范化意味着可以在不影响旧事件的情况下编辑时间表,并且可以单独编辑事件而不影响时间表或其他事件。您只需多做一点工作就可以获得更大的灵活性。

也许你应该有 3 类(课程、时间表和课程发生),而不仅仅是时间表和发生。

class Lesson < ActiveRecord::Base
  # Has attributes like
  #  :type (the type of exercise that will be taught, say Spin, Kickboxing)
  has_many :schedules
end

class Schedule < ActiveRecord::Base
  # Has attributes like
  #  :starts_at (time)
  #  :occurs_on (weekday name represented as integer)
  #  :duration
  belongs_to :lesson
  belongs_to :location
end

class LessonOccurrence < ActiveRecord::Base
  # Has attributes like
  #  :date
  #  :start_time
  #  :duration
  belongs_to :lesson
  belongs_to :teacher
  belongs_to :location
end

class Teacher < ActiveRecord::Base
  has_many :lesson_occurrences
end

因此,类型为 "kickboxing" 的课程可能每周上课 3 次,因此它具有三个计划对象。然后,当从 lesson_occurrences 中创建一周的时间表时,3 个 lesson_occurrence 对象被添加到该课程,每个对象都从 3 个时间表对象中的每一个中获取其时间和持续时间。

在你的情况下,我看不出有什么方法可以避免时间和持续时间之间的重复,但我认为就像 MarsAtomic 所建议的那样,你应该将它们视为不同种类的事物——时间表包含建议的时间和持续时间,并且 lesson_occurrences持有实际的。

现在我想起来了,这个答案在本质上与 MarsAtomic 的答案相同 - 因为根据应用程序的其余部分,将时间表拆分为课程和时间表可能不会给您带来太多好处。