自定义验证器以防止 Rails 4 应用程序中的重叠约会?

cod*_*red 2 validation ruby-on-rails

我需要帮助编写自定义验证以防止 Rails 4 应用程序中的重叠约会。我正在编写这个应用程序来自学 Ruby 和 Rails。在研究这个问题时,我发现了一个名为 ValidatesOverlap 的 gem,但我想编写自己的验证器以供学习。

我的约会模型有一个日期时间数据类型的“appointment_at”列和时间数据类型的“持续时间”列。Appointment 模型与 Member 和 Trainer 模型具有“has_many :through”关联。约会:

belongs_to :member
belongs_to :trainer
Run Code Online (Sandbox Code Playgroud)

约会模型中的现有验证包括:

validates :member, uniqueness: {scope: :appointment_at, message: "is booked already"}
validates :trainer, uniqueness: {scope: :appointment_at, message: "is booked already"}
Run Code Online (Sandbox Code Playgroud)

自定义验证器需要防止成员或培训师安排重叠约会。现在,我可以防止将“重复约会”保存到数据库中,但无法阻止“重叠”约会。例如,如果 trainer_1 与 member_1 预约了 1 小时的约会(从早上 7:00 开始),我的模型验证会阻止 member_2 与 trainer_1 预约早上 7:00 的约会。但是,我目前没有办法阻止 member_2 在早上 7:01 安排与 trainer_1 的会话!我正在处理两个属性:“appointment_at”,它是开始时间,“持续时间”,它是约会的总时间。如果我可以轻松地从“appointment_at”和“

我很感激关于如何解决重叠约会问题的任何想法或建议(不使用 gem)。提前谢谢了!

Hia*_*nho 5

不久前我遇到了同样的问题。您需要一个 scope :overlapping,它读取约会的重叠约会和要检查的验证器。此示例适用于 PostgreSQL 数据库。如果您使用另一个数据库,则必须为您的数据库调整它。

class Appointment < ActiveRecord::Base

  belongs_to :member
  belongs_to :trainer

  validate :overlapping_appointments

  scope :overlapping, ->(a) {
     where(%q{ (appointment_at, (appointment_at + duration)) OVERLAPS (?, ?) }, a.appointment_at, a.appointment_to)
    .where(%q{ id != ? }, a.id)
    .where(trainer_id: a.trainer.id)
  }

  def find_overlapping
    self.class.overlapping(self)
  end

  def overlapping?
    self.class.overlapping(self).count > 0
  end

  def appointment_to
    (appointment_at + duration.hour.hours + duration.min.minutes + duration.sec.seconds).to_datetime
  end

  protected

  def overlapping_appointments
    if overlapping?
      errors[:base] << "This appointment overlaps with another one."  
    end
  end

end
Run Code Online (Sandbox Code Playgroud)

试一试,如果对你有帮助,请告诉我。