【问题标题】:Cast Rails range to Postgres rangeCast Rails 范围到 Postgres 范围
【发布时间】:2014-06-20 08:46:03
【问题描述】:

我想知道在数据库中查找行时是否可以强制 Rails 将范围转换为 postgres 范围 我的数据库中有一个日期范围列类型的表

 create_table "events", force: true do |t|
   ......
    t.daterange "date"

  end

当我插入新行时,Rails 知道如何转换范围 例如

Event.create date: Date.today..Date.tomorrow 

按预期工作,我在“事件”表中得到一个新行,日期值等于“[2014-07-16,2014-07-17)”

但是当我尝试使用 to_formatted(:db) 方法从 db Rails 强制转换范围中选择行时 所以

range = Date.today..Date.tomorrow
Event.find_by date:range

变成

SELECT  "events".* FROM "events"  WHERE ("events"."date" BETWEEN 2014-07-16 AND 2014-07-17) LIMIT 1

而我期望得到的是

SELECT  "events".* FROM "events"  WHERE ("events"."date" [2014-07-16, 2014-07-17) LIMIT 1

我通过向 RANGE_FORMATS 添加新的格式化程序扩展了核心 Range 类

现在使用

Event.find_by date:range.to_s(:pg)

有没有更有效的方法解决问题?

【问题讨论】:

    标签: ruby-on-rails postgresql range


    【解决方案1】:

    我知道这是一个 2 年前的问题,但我遇到了类似的问题并想分享我的解决方法。

    我在 ActiveRecord 模型中定义了一个范围:

    scope :score_range, ->(score_range) {
        where('course_placement_rubrics.score_range @> numrange(?)', score_range)
    }
    

    我这样称呼这个作用域:

    CoursePlacementRubric.score_range( (0..5.0)  )
    

    ActiveRecord 构建了以下查询:

    SELECT "course_placement_rubrics".*
    FROM "course_placement_rubrics"
    WHERE (course_placement_rubrics.score_range @> numrange(0,1,2,3,4,5))
    

    ActiveRecord 尝试提供帮助并迭代我的范围。在您的情况下,ActiveRecord 会尝试提供帮助并使用 BETWEEN..AND 谓词。这显然不是我和你想要的。

    这是我的简单解决方法:

    scope :score_range, ->(score_range) {
        where('course_placement_rubrics.score_range @> numrange(?, ?)', score_range.first, score_range.last)
    }
    

    这会输出我想要的查询:

    SELECT "course_placement_rubrics".*
    FROM "course_placement_rubrics"
    WHERE (course_placement_rubrics.score_range @> numrange(0, 5))
    

    希望这对某人有所帮助。

    【讨论】:

      【解决方案2】:

      这是 AR 的默认行为。如果你在 AR 源码中看到:

      https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/predicate_builder.rb#L112

      这是要去 Arel in 方法:

      https://github.com/rails/arel/blob/master/lib/arel/predications.rb#L27

      所以如果你想拥有更漂亮的代码,你需要重写这个in方法。

      【讨论】:

      • 我的意思是我想查找范围相同的记录,而不是范围包括给定值的记录
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-13
      • 2016-07-11
      • 1970-01-01
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多