我需要帮助编写自定义验证以防止在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”值轻松计算“结束时间”,我宁愿保留这些属性/列。我还没弄明白怎么做:)
我很感激有关如何解决重叠约会问题的任何想法或建议(不使用宝石)。非常感谢提前!
答案 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
尝试一下,如果有帮助,请告诉我。