我想知道在DB中查找行时是否可以强制Rails将范围转换为postgres范围 我的数据库中有一个表,日期范围列类型为
create_table "events", force: true do |t|
......
t.daterange "date"
end
当我插入新行时,Rails知道如何转换范围 E.g
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)
有更有效的方法来解决问题吗?
答案 0 :(得分:2)
我知道这是一个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))
希望这有助于某人。
答案 1 :(得分:1)
这是AR的默认行为。如果您在AR来源中看到:
这是Arel in
方法:
https://github.com/rails/arel/blob/master/lib/arel/predications.rb#L27
因此,如果您想拥有更漂亮的代码,则需要覆盖此in
方法。