代码之家  ›  专栏  ›  技术社区  ›  Nerian

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

  •  1
  • Nerian  · 技术社区  · 9 年前

    根据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 回复  |  直到 9 年前
        1
  •  1
  •   pozs    9 年前

    你的 if 逻辑似乎是可靠的。也许你可以简化一些,比如

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

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

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