如何在Rails中查询日期范围?

时间:2017-01-30 14:56:03

标签: ruby-on-rails postgresql

根据Rails指南,您将如何查询范围:

http://edgeguides.rubyonrails.org/active_record_postgresql.html#range-types

## All Events on a given date
Event.where("dates @> ?::date", Date.new(2014, 2, 12))

但是如何在日期范围内获取所有事件?

我知道我可以这样做:

Event.where("dates && daterange(?, ?)", date1, date2)

但是这个日期范围默认使用'[)'作为边界。有没有办法提供范围而不是两个日期,以便自动考虑实际边界?

请注意,这些是不同的:

date1..date2  !=   date1...date2

到目前为止,我正在这样做:

if dates.exclude_end?
  Event.where("dates && daterange(?, ?, '[)')", dates.begin, dates.end)
else
  Event.where("dates && daterange(?, ?, '[]')", dates.begin, dates.end)
end

但是有更好的方法吗?我会喜欢这样的东西:

Event.where("dates && ?::daterange)", dates)

编辑:

就我而言,dates是日期范围。

[6] pry(main)> Reservation.where(dates:     Date.current..4.days.from_now.to_date).explain

Reservation Load (0.8ms)  SELECT "reservations".* FROM "reservations" WHERE ("reservations"."dates" BETWEEN $1 AND $2)  [["dates", Mon, 30 Jan 2017], ["dates", Fri, 03 Feb 2017]]

ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR:  malformed range literal: "2017-01-30"

1 个答案:

答案 0 :(得分:1)

您的if逻辑看起来很稳固。也许你可以更简化它,比如

Event.where("dates && daterange(?, ?, ?)",
            dates.begin, dates.end, dates.exclude_end? ? '[)' : '[]')

这样,所有变量都是绑定参数&不必使用2个不同的查询。

daterange是PostgreSQL特定类型,因此在ORM中得不到很好的支持。 (另外,似乎ActiveRecord将范围绑定为BETWEEN表达式,因此您无法将它们绑定为值)。