自定义验证器以防止 Rails 4 应用程序中的重叠约会?
Custom validator to prevent overlapping appointments in Rails 4 app?
我需要帮助编写自定义验证以防止 Rails 4 应用程序中的约会重叠。我编写此应用程序是为了自学 Ruby & Rails。在研究这个问题时,我发现了一个名为 ValidatesOverlap 的 gem,但我想编写自己的验证器以供学习之用。
我的约会模型有一个 "appointment_at" 日期时间数据类型的列和一个 "duration" 时间数据类型的列。 Appointment 模型与 Member 和 Trainer 模型有 "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"}
自定义验证器需要防止成员或培训师安排重叠的约会。现在,我可以阻止 "duplicate appointments" 被保存到数据库,但不能阻止 "overlapping" 的。例如,如果 trainer_1 与 member_1 预约了 1 小时的约会,开始于 7:00 上午,我的模型验证阻止 member_2 与 [=27= 预约] 7:00 上午。但是,我目前没有办法阻止 member_2 为 7:01 安排与 trainer_1 的会话!我正在处理两个属性:"appointment_at," 是开始时间,"duration" 是约会的总时间。如果我可以轻松地从 "appointment_at" 和 "duration" 值计算出 "end time",我宁愿保留那些 attributes/columns。我还不知道该怎么做:)
对于如何解决约会重叠问题(不使用 gem)的任何想法或建议,我将不胜感激。非常感谢!
我刚才遇到了同样的问题。您需要一个作用域 :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
试一试,如果对您有帮助,请告诉我。
我需要帮助编写自定义验证以防止 Rails 4 应用程序中的约会重叠。我编写此应用程序是为了自学 Ruby & Rails。在研究这个问题时,我发现了一个名为 ValidatesOverlap 的 gem,但我想编写自己的验证器以供学习之用。
我的约会模型有一个 "appointment_at" 日期时间数据类型的列和一个 "duration" 时间数据类型的列。 Appointment 模型与 Member 和 Trainer 模型有 "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"}
自定义验证器需要防止成员或培训师安排重叠的约会。现在,我可以阻止 "duplicate appointments" 被保存到数据库,但不能阻止 "overlapping" 的。例如,如果 trainer_1 与 member_1 预约了 1 小时的约会,开始于 7:00 上午,我的模型验证阻止 member_2 与 [=27= 预约] 7:00 上午。但是,我目前没有办法阻止 member_2 为 7:01 安排与 trainer_1 的会话!我正在处理两个属性:"appointment_at," 是开始时间,"duration" 是约会的总时间。如果我可以轻松地从 "appointment_at" 和 "duration" 值计算出 "end time",我宁愿保留那些 attributes/columns。我还不知道该怎么做:)
对于如何解决约会重叠问题(不使用 gem)的任何想法或建议,我将不胜感激。非常感谢!
我刚才遇到了同样的问题。您需要一个作用域 :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
试一试,如果对您有帮助,请告诉我。