Skip to content

Instantly share code, notes, and snippets.

@danielyaa5
Created February 7, 2020 06:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielyaa5/73baef4a5c3c33303c40307f30e0d891 to your computer and use it in GitHub Desktop.
Save danielyaa5/73baef4a5c3c33303c40307f30e0d891 to your computer and use it in GitHub Desktop.
# frozen_string_literal: true
class AvailabilitiesController < AuthenticatedController
before_action :authenticate_interviewer!
def index
respond_to do |format|
format.json do
render json: Availability.where(interviewer: @interviewer)
end
end
end
def create
merge_times = overlap
if merge_times.empty?
Availability.create! availability_params
else
all_times = merge_times + [availability_params]
new_start_at = all_times.min_by { |mt| mt[:slot].begin }[:slot].begin
new_end_at = all_times.max_by { |mt| mt[:slot].end }[:slot].end
Availability.transaction do
Availability.create!(slot: (new_start_at..new_end_at), interviewer: @interviewer)
merge_times.each(&:destroy!)
end
end
head :ok
end
def delete
range = availability_params[:slot]
overlap.each do |availability|
curr_slot = availability[:slot]
if range.begin <= curr_slot.begin && range.end <= curr_slot.end
availability.update!(slot: (range.end..curr_slot.end))
elsif range.begin >= curr_slot.begin && range.end >= curr_slot.end
availability.update!(slot: (curr_slot.begin..range.end))
else
remove_overlap(curr_slot, range, availability)
end
end
end
private
def remove_overlap(curr_slot, range, availability)
Availability.transaction do
Availability.create!(slot: (curr_slot.begin..range.begin), interviewer: @interviewer)
Availability.create!(slot: (range.end..curr_slot.begin), interviewer: @interviewer)
availability.destroy!
end
end
def overlap
start_at = availability_params[:slot].begin
end_at = availability_params[:slot].end
merge_times = Availability.where('slot -|- tstzrange(?, ?)', start_at, end_at)
merge_times + Availability.where('slot && tstzrange(?, ?)', start_at, end_at)
end
def availability_params
start_at = DateTime.parse(params.require(:start))
end_at = DateTime.parse(params.require(:end))
raise 'Date to early' if start_at < DateTime.now || end_at < DateTime.now
raise 'Bad range' if start_at >= end_at
{
slot: (start_at..end_at),
interviewer: @interviewer
}
rescue StandardError
render json: { message: 'Bad date params' }, status: :unprocessable_entity
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment