I'm trying to get a list of available meeting rooms
by office_id
where the availability is depending on the bookings
with selected_start_time
and selected_end_time
Here's my schema
defmodule MyApp.Context.Booking do
schema "bookings" do
field :start_time, :utc_datetime
field :end_time, :utc_datetime
belongs_to :meeting_room, MyApp.Context.MeetingRoom, foreign_key: :meeting_room_id
timestamps()
end
end
defmodule MyApp.Context.MettingRoom do
schema "meeting_rooms" do
belongs_to :office, MyApp.Context.Office, foreign_key: :office_id
has_many :bookings, MyApp.Context.Booking
timestamps()
end
end
defmodule MyApp.Context.Office do
schema "offices" do
field :name, :string
has_many :meeting_rooms, MyApp.Context.MeetingRoom
timestamps()
end
end
What I've already tried using fragment
. It worked if there is no booking
created for a selected time. After creating a booking
for meeting_room_id = 1
it will show an empty list even though it still has another available meeting_room
which is meeting_room_id = 2
def list_available_meeting_rooms(office_id, selected_start_time, selected_end_time) do
query = from office in Office,
where: office.id == ^office_id,
join: meeting_rooms in assoc(office, :meeting_rooms),
where: fragment("NOT EXISTS (SELECT * FROM bookings WHERE start_time < ? AND ? < end_time)",
^selected_end_time, ^selected_start_time),
select: meeting_rooms
Repo.all(query)
end
This statement will check for overlaping start_time
and end_time
. You can check here Algorithm to detect overlapping periods
fragment("NOT EXISTS (SELECT * FROM bookings WHERE start_time < ? AND ? < end_time)", ^selected_end_time, ^selected_start_time)
The expected result should return a list of available meeting_rooms
For example:
offices
id | name
1 | Office 1
meeting_rooms
id | office_id
1 | 1
2 | 1
3 | 1
4 | 1
bookings
id | start_time | end_time | meeting_room_id
1 | 2019-09-17 03:00:00Z | 2019-09-17 04:00:00Z | 1
2 | 2019-09-17 03:00:00Z | 2019-09-17 04:00:00Z | 2
When querying the list of available meeting rooms by office_id
and start_time = 2019-09-17 03:00:00Z
and end_time = 2019-09-17 04:00:00Z
it should return only meeting_rooms
id 3 and 4.
How do I achieve this kind of result?
Any kind of help would be great. Thanks in advance!