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

时间:2015-01-08 06:23:30

标签: ruby-on-rails validation

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

我的约会模型具有datetime数据类型的“appointment_at”列和time数据类型的“duration”列。约会模型与成员和培训师模型有“has_many:through”关联。任命:

belongs_to :member
belongs_to :trainer

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

validates :member, uniqueness: {scope: :appointment_at, message: "is booked already"}
validates :trainer, uniqueness: {scope: :appointment_at, message: "is booked already"}

自定义验证程序需要阻止成员或培训师安排重叠约会。现在,我可以防止“重复约会”被保存到数据库,但不能阻止“重叠”约会。例如,如果training_1与member_1预约1小时预约,该会员从早上7点开始,我的模型验证会阻止member_2在上午7:00与trainer_1预约。但是,我目前没有办法阻止member_2在7:01 am安排与trainer_1的会话!我正在使用两个属性:“appointment_at”,即开始时间和“持续时间”,即约会的总时间。如果我可以从“appointment_at”和“duration”值轻松计算“结束时间”,我宁愿保留这些属性/列。我还没弄明白怎么做:)

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

1 个答案:

答案 0 :(得分:3)

前一段时间我遇到了同样的问题。您需要一个范围: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

尝试一下,如果有帮助,请告诉我。