I struggle with creating a performant select of the database.
Following case:
A booking has 2 attributes departure
and arrival
.
Both attributes are type date
.
I want to select all Persons with bookings with departure: 1.month.ago
and no Booking in the future.
Relation:
class Booking
has_many :persons, class_name: 'Person', through: :stays
end
class Stay
belongs_to :booking, class_name: 'Booking'
belongs_to :person, class_name: 'Person'
end
class Person
has_many :bookings, class_name: 'Booking', through: :stays
end
Because there are ~3.800.000 Persons in the database I can’t work with a selection by a ruby logic after selection.
I’ve tried some requests, but I do not get any result, even there are some.
Person.joins(:bookings).where('bookings.departure < ? AND NOT EXISTS (SELECT 1 FROM bookings WHERE arrival >= ?)', 1.month.ago, Time.zone.today).find_each(&:clear)
Is it possible to have such a Database request, or do I need to work with one case in active record and the others by a logic?
Person.joins(:bookings).where('bookings.departure < ?', 1.month.ago).find_each do |pers|
pers.clear unless pers.bookings.where('arrival >= ?', Time.zone.today).exists?
end
2
Answers
Does something like this work for you?
It appears you are just missing joining a join here:
You will need to change this to
We should be able to convert this query in the ActiveRecord/Arel as follows:
This should result in the following query