Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add constraint to avoid creating duplicate time offs #210

Merged
merged 1 commit into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/controllers/time_offs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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
9 changes: 7 additions & 2 deletions app/models/time_off.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand All @@ -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
8 changes: 8 additions & 0 deletions db/migrate/20240613151647_add_unique_index_to_time_offs.rb
Original file line number Diff line number Diff line change
@@ -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
3 changes: 2 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions spec/factories/time_offs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down
5 changes: 3 additions & 2 deletions spec/models/time_off_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down
Loading