From fd6afff460aa8765d86f823f04766fa2c924dd8d Mon Sep 17 00:00:00 2001 From: Kaio Magalhaes Date: Thu, 13 Jun 2024 12:20:06 -0300 Subject: [PATCH] add constraint to avoid creating duplicate time offs --- app/controllers/time_offs_controller.rb | 4 ++-- app/models/time_off.rb | 9 +++++++-- .../20240613151647_add_unique_index_to_time_offs.rb | 8 ++++++++ db/schema.rb | 3 ++- spec/factories/time_offs.rb | 5 +++-- spec/models/time_off_spec.rb | 5 +++-- 6 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 db/migrate/20240613151647_add_unique_index_to_time_offs.rb diff --git a/app/controllers/time_offs_controller.rb b/app/controllers/time_offs_controller.rb index 89f772b..43779be 100644 --- a/app/controllers/time_offs_controller.rb +++ b/app/controllers/time_offs_controller.rb @@ -10,7 +10,7 @@ def create end time_off = TimeOffBuilder.call(text, start_datetime, end_datetime) - time_off&.save + time_off&.save! success = time_off&.persisted? msg = success ? { id: time_off&.id } : 'The time of request creation failed' @@ -44,6 +44,6 @@ def end_datetime end def time_off_params - params.require(:webhook_time_off).permit(:text, :start_datetime, :end_datetime).to_h + params.permit(:text, :start_datetime, :end_datetime).to_h end end diff --git a/app/models/time_off.rb b/app/models/time_off.rb index 3afcf60..00ddf07 100644 --- a/app/models/time_off.rb +++ b/app/models/time_off.rb @@ -14,8 +14,9 @@ # # Indexes # -# index_time_offs_on_time_off_type_id (time_off_type_id) -# index_time_offs_on_user_id (user_id) +# index_time_offs_on_time_off_type_id (time_off_type_id) +# index_time_offs_on_unique_combination (starts_at,ends_at,time_off_type_id,user_id) UNIQUE +# index_time_offs_on_user_id (user_id) # # Foreign Keys # @@ -29,5 +30,9 @@ class TimeOff < ApplicationRecord validates :starts_at, presence: true validates :ends_at, presence: true + validates :user_id, + uniqueness: { scope: %i[starts_at ends_at time_off_type_id], + message: 'Time off with the same start and end times already exists for this user and time off type' } + scope :active_in_period, ->(start_date, end_date) { where('starts_at <= ? AND ends_at >= ?', end_date, start_date) } end diff --git a/db/migrate/20240613151647_add_unique_index_to_time_offs.rb b/db/migrate/20240613151647_add_unique_index_to_time_offs.rb new file mode 100644 index 0000000..1f42db3 --- /dev/null +++ b/db/migrate/20240613151647_add_unique_index_to_time_offs.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class AddUniqueIndexToTimeOffs < ActiveRecord::Migration[7.0] + def change + add_index :time_offs, %i[starts_at ends_at time_off_type_id user_id], unique: true, + name: 'index_time_offs_on_unique_combination' + end +end diff --git a/db/schema.rb b/db/schema.rb index 353da98..2f5f52a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_06_05_183622) do +ActiveRecord::Schema[7.0].define(version: 2024_06_13_151647) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "plpgsql" @@ -299,6 +299,7 @@ t.datetime "ends_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["starts_at", "ends_at", "time_off_type_id", "user_id"], name: "index_time_offs_on_unique_combination", unique: true t.index ["time_off_type_id"], name: "index_time_offs_on_time_off_type_id" t.index ["user_id"], name: "index_time_offs_on_user_id" end diff --git a/spec/factories/time_offs.rb b/spec/factories/time_offs.rb index 738a41f..9b97104 100644 --- a/spec/factories/time_offs.rb +++ b/spec/factories/time_offs.rb @@ -14,8 +14,9 @@ # # Indexes # -# index_time_offs_on_time_off_type_id (time_off_type_id) -# index_time_offs_on_user_id (user_id) +# index_time_offs_on_time_off_type_id (time_off_type_id) +# index_time_offs_on_unique_combination (starts_at,ends_at,time_off_type_id,user_id) UNIQUE +# index_time_offs_on_user_id (user_id) # # Foreign Keys # diff --git a/spec/models/time_off_spec.rb b/spec/models/time_off_spec.rb index f6b1342..6ecbe16 100644 --- a/spec/models/time_off_spec.rb +++ b/spec/models/time_off_spec.rb @@ -14,8 +14,9 @@ # # Indexes # -# index_time_offs_on_time_off_type_id (time_off_type_id) -# index_time_offs_on_user_id (user_id) +# index_time_offs_on_time_off_type_id (time_off_type_id) +# index_time_offs_on_unique_combination (starts_at,ends_at,time_off_type_id,user_id) UNIQUE +# index_time_offs_on_user_id (user_id) # # Foreign Keys #