如何validationRails中的重叠时间

我有一个Event model ,它在我的日程安排应用程序中有时间和时间,我想在保存之前validation重叠时间。

我的观点图如下;

 Departure date: Dec 31, 2016 Day1 07:00 - 07:20 event1 10:30 - 11:30 event2 15:40 - 16:10 event3 [add event button] Day2 08:15 - 09:05 event4 12:08 - 13:04 event5 14:00 - 14:25 event6 [add event button] [save schedule button] 

from时间和时间可以同时改变和添加。

我想做的是显示错误,如果我尝试为Day1添加(或更改) 07:05 - 07:30 ,例如, 13:50 - 14:30 ,依此类推。

虽然我尝试了一些overlap代码, between 这篇文章或这篇post等等之后,我无法将它们应用到我的代码中。

schema.rb

  create_table "events", force: :cascade do |t| t.time "from" t.time "to" t.integer "room_id" ... create_table "rooms", force: :cascade do |t| t.integer "schedule_id" ... create_table "schedules", force: :cascade do |t| t.integer "user_id" t.date "departure_date" ... 

提供以下型号

 class Schedule < ActiveRecord::Base belongs_to :user has_many :rooms, inverse_of: :schedule accepts_nested_attributes_for :rooms, allow_destroy: true ... class Room < ActiveRecord::Base belongs_to :schedule, inverse_of: :rooms has_many :events, inverse_of: :room accepts_nested_attributes_for :events, allow_destroy: true ... class Event < ActiveRecord::Base belongs_to :room, inverse_of: :events has_one :schedule, autosave: false, through: :room ... 

_schedule_form.html.erb

     
(f.object.departure_date.strftime('%b/%d/%Y') if f.object.departure_date), class: 'form-control' %>
$(function () { $('#datetimepicker').datetimepicker({format:'MMM-DD-YYYY'}); });
<div id="room_">

Day 

   -   

如果你能告诉我如何检查和显示错误,将不胜感激。

编辑!

还是不行

event.rb

 class Event  range { where('(\'from\' BETWEEN ? AND ?)', range.first, range.last) } scope :exclude_self, -> id { where.not(id: id) } def cannot_overlap_another_event range = Range.new from, to overlaps = Event.exclude_self(id).in_range(range) overlap_error unless overlaps.empty? end def overlap_error errors.add(:overlap_error, 'There is already an event scheduled in this hour!') end 

development.log

 .... Started POST "/schedules" for 218.33.213.91 at 2016-04-07 11:44:59 +0000 Processing by SchedulesController#create as HTML ... [1m[35m (0.5ms)[0m begin transaction [1m[36m (0.5ms)[0m [1mSELECT COUNT(*) FROM "events" WHERE ("events"."id" IS NOT NULL) AND (('from' BETWEEN '2016-04-07 07:00:00.000000' AND '2016-04-07 07:20:00.000000'))[0m [1m[35m (0.3ms)[0m SELECT COUNT(*) FROM "events" WHERE ("events"."id" IS NOT NULL) AND (('from' BETWEEN '2016-04-07 07:05:00.000000' AND '2016-04-07 07:30:00.000000')) [1m[36mSQL (0.5ms)[0m [1mINSERT INTO "schedules" ("title", "departure_date", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)[0m [["title", "test title"], ["departure_date", "2016-04-10"], ["user_id", 1], ["created_at", "2016-04-07 11:45:00.061460"], ["updated_at", "2016-04-07 11:45:00.061460"]] ... 

好吧,如果您需要服务器端validation,您可以在模型类中实现一些customvalidation器:

 validate :cannot_overlap_another_event 

接下来,您需要自己编写此方法的代码:

 def cannot_overlap_another_event range = Range.new from, to overlaps = Appointment.exclude_self(id).in_range(range) overlap_error unless overlaps.empty? end 

解释此代码的作用,您可以使用fromto日期创建Range对象。 然后,它使用辅助作用域来排除Event本身,并检查是否存在此范围内的事件。

 scope :in_range, -> range { where('(from BETWEEN ? AND ?)', range.first, range.last) } scope :exclude_self, -> id { where.not(id: id) } 

overlap_error是一个填充模型错误哈希以在屏幕上显示的方法:

 def overlap_error errors.add(:overlap_error, 'There is already an event scheduled in this hour!') end 

在您的EventsController#CreateEventsController#Update方法检查旧时间之间的新时间,例如:

 events = Event.where(:departure_date => event_params[:departure_date]) events.each do |event| if event_params[:to].between?(event.to, event.from) || event_params[:from].between?(event.to, event.from) flash[:error] = "Current Slot Time is already taken!" redirect_to :back return end end 

看看这个https://makandracards.com/makandra/984-test-if-two-date-ranges-overlap-in-ruby-or-rails 。 关键是要为重叠的兄弟姐妹定义一个范围。 像这样的东西:

 # Return a scope for all interval overlapping the given interval, including the given interval itself named_scope :overlapping, lambda { |interval| { :conditions => ["id <> ? AND (DATEDIFF(start_date, ?) * DATEDIFF(?, end_date)) >= 0", interval.id, interval.end_date, interval.start_date] }} 

你也可以查看这个gem: https : //github.com/robinbortlik/validates_overlap我认为它可以提供帮助。