简体   繁体   中英

Rails scope filter by date range

There are many questions relate to rails date range problem but mine is a little more complicated.

I have two models: house and booking. A House has_many bookings. A Booking has two attributes in date format: check_in and check_out.

What I want to achieve: Giving a valid date range, show all houses that are available during this range. In detail:

  • The start date of the range should not be in any booking.
  • The end date of the range should not be in any booking.
  • There should not be any booking between the start and the end.

Can this be done using the rails scope?

UPDATE:

I found the code below that can check scope date interval that overlaps.

named_scope :overlapping, lambda { |interval| {
:conditions => ["id <> ? AND (DATEDIFF(start_date, ?) * DATEDIFF(?, end_date)) >= 0", interval.id, interval.end_date, interval.start_date]
}}

How can I transfer this to my problem?

scope :overlapping, (lambda do |start_date, end_date|
  House.includes(:bookings).where("bookings.check_in < ? AND bookings.check_out > ?", 
  start_date, end_date).references(:bookings).uniq
end)

I went ahead and deleted the >= and <= operators in favor of > and < to explicitly show these bookings being outside of the given range, but you can adjust them per your needs!

Update

Changed query to use #includes instead of #joins , since we're querying the attached table.

Yes it is possible to have this query through scope. Put this scope in house model.

scope :overlapping, -> (start_date, end_date) { 
  includes(:bookings).where('bookings.check_in < ? AND bookings.check_out > ?',
  start_date.to_date, end_date.to_date)
}

And call as House.overlapping('2015-07-01', '2015-07-09')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM