Я только что написал простое приложение, чтобы проверить это. Вот что я использовал для проверки модели.
class Booking < ActiveRecord::Base
validate :uniqueness_of_date_range
private
def uniqueness_of_date_range
errors.add(:start_date, "is not available") unless Room.where("? >= start_date AND ? <= end_date",
start_date, start_date).count == 0
errors.add(:end_date, "is not available") unless Room.where("? >= start_date AND ? <= end_date",
end_date, end_date).count == 0
end
end
Первая пользовательская проверка проверяет, попадает ли начальная дата текущей записи между начальной и конечной датой любой записи, а вторая делает то же самое для конечной даты. Возможно, вы захотите показать лучшее сообщение об ошибке (например, какая дата начала / окончания записи (записей), которые / находятся в конфликте с текущей, делают аналогичный запрос (используя .all вместо .count и добавляя детали соответствия номеров).
Вот миграция БД, которую я использовал
class CreateBookings < ActiveRecord::Migration
def self.up
create_table :bookings do |t|
t.date :start_date
t.date :end_date
t.string :title
t.timestamps
end
end
def self.down
drop_table :bookings
end
end