Ste*_*ies 2 postgresql ruby-on-rails rails-activerecord ruby-on-rails-5
就像标题所问的那样,如何在查询中包含日期范围?
例如,假设我有一个名为的模型VisitToGrandma,它有一个名为visit_date. 现在,我想找到上个月发生的所有对祖母的访问。
这是我正在尝试的:
VisitToGrandma.where("? @> visit_date", (1.month.ago..Time.now))
Run Code Online (Sandbox Code Playgroud)
但是,这会产生查询:
SELECT "visits_to_grandmas".* FROM "visits_to_grandmas" WHERE ('2018-07-01','2018-07-02','2018-07-03','2018-07-04','2018-07-05 ','2018-07-06','2018-07-07','2018-07-08','2018-07-09','2018-07-10','2018-07-11', '2018-07-12'、'2018-07-13'、'2018-07-14'、'2018-07-15'、'2018-07-16'、'2018-07-17'、'2018 -07-18','2018-07-19','2018-07-20','2018-07-21','2018-07-22','2018-07-23','2018-07 -24'、'2018-07-25'、'2018-07-26'、'2018-07-27'、'2018-07-28'、'2018-07-29'、'2018-07-30 ','2018-07-31','2018-08-01'@>visit_date)
参数化这个的正确方法是什么?
是的,我知道对于这个虚构的例子,我可以只使用开始和结束日期并使用BETWEEN或其他一些运算符来执行此操作,而无需使用实际日期范围,但这不是我要问的。
编辑以指出这个问题与另一个问题的不同之处:
这个问题只是关于在一个范围内找到一个日期,我的问题是询问如何实际参数化一个范围对象,以便可以使用所有 postgresql 的日期范围运算符。
正如我最近在另一个PostgreSQL/range/ActiveRecord回答中提到的,AR 与 PostgreSQL 的范围类型的集成是有限的。
您可以通过半手动生成您想要的范围的字符串表示来解决这个问题:
ActiveRecord::Base.connection.type_cast(1.month.ago.to_date .. Time.now.to_date)
Run Code Online (Sandbox Code Playgroud)
不是#to_date获取日期而不是时间戳的调用。你也可以说:
today = Date.today
ActiveRecord::Base.connection.type_cast(today.months_ago(1) .. today)
Run Code Online (Sandbox Code Playgroud)
将其与您的查询混合:
today = Date.today
VisitToGrandma.where(
'? @> visit_date',
VisitToGrandma.connection.type_cast(today.months_ago(1) .. today)
)
Run Code Online (Sandbox Code Playgroud)
根据上下文,您可能可以更轻松/更清晰地访问connection. 您可能想要包含一个类型转换,以确保没有任何误解:
today = Date.today
VisitToGrandma.where(
'?::daterange @> visit_date',
VisitToGrandma.connection.type_cast(today.months_ago(1) .. today)
)
Run Code Online (Sandbox Code Playgroud)