自定义验证器以防止 Rails 4 应用程序中的重叠约会? [英] Custom validator to prevent overlapping appointments in Rails 4 app?

查看:38
本文介绍了自定义验证器以防止 Rails 4 应用程序中的重叠约会?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need help writing a custom validation to prevent overlapping appointments in a Rails 4 app. I'm coding this app to teach myself Ruby & Rails. While researching the issue, I discovered a gem called ValidatesOverlap, but I want to write my own validator for learning purposes.

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

My Appointment model has an "appointment_at" column of the datetime datatype and a "duration" column of the time datatype. The Appointment model has a "has_many :through" association with Member and Trainer models. Appointments:

belongs_to :member
belongs_to :trainer

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

Existing validations in the Appointment model include:

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

自定义验证器需要防止成员或培训师安排重叠约会.现在,我可以防止将重复约会"保存到数据库中,但无法阻止重叠"约会.例如,如果 trainer_1 与 member_1 预约了 1 小时的约会(从早上 7:00 开始),我的模型验证会阻止 member_2 与 trainer_1 预约早上 7:00 的约会.但是,我目前没有办法阻止 member_2 在早上 7:01 安排与 trainer_1 的会话!我正在处理两个属性:appointment_at",它是开始时间,持续时间",它是约会的总时间.如果我可以从appointment_at"和duration"值轻松计算结束时间",我更愿意保留这些属性/列.我还没有想出如何做到这一点:)

The custom validator needs to prevent members or trainers from scheduling overlapping appointments. Right now, I can prevent "duplicate appointments" from being saved to the database, but can't stop "overlapping" ones. For example, if trainer_1 is booked for a 1 hour appointment with member_1 which starts at 7:00 am, my model validations prevent member_2 from booking an appointment with trainer_1 for 7:00 am. However, I have no current means of preventing member_2 from scheduling a session with trainer_1 for 7:01 am! I'm working with two attributes: "appointment_at," which is the start time and "duration" which is the total time of an appointment. I'd prefer to keep those attributes/columns if I can easily calculate "end time" from the "appointment_at" and "duration" values. I haven't figured out how to do that yet :)

如果您就如何解决重叠约会问题(不使用 gem)提出任何想法或建议,我将不胜感激.非常感谢!

I'd appreciate any thoughts or suggestions about how I can approach solving the problem of overlapping appointments (without using a gem). Many thanks in advance!

推荐答案

我不久前遇到了同样的问题.您需要一个范围 :overlapping,它读取约会的重叠约会和要检查的验证器.此示例适用于 PostgreSQL 数据库.如果您使用的是其他数据库,则必须针对您的数据库进行调整.

I had the same problem a while ago. You need a scope :overlapping, that reads overlapping appointments for an appointment and a validator to check. This example is for a PostgreSQL DB. You have to adjust it for your DB, if you're using another DB.

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

尝试一下,如果对您有帮助,请告诉我.

Give it a try and let me know, if it helped you.

这篇关于自定义验证器以防止 Rails 4 应用程序中的重叠约会?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆