【问题标题】:How to check if a number is within range in activerecord?如何检查数字是否在活动记录的范围内?
【发布时间】:2018-07-28 17:44:29
【问题描述】:

我有一个带有范围列的模型

#<JobRequirement id: 1, age: 18...30>

如何使用age: 20 获取JobRequirement

有点像

JobRequirement.where(age: 20)

【问题讨论】:

  • 数据库里面age是哪个数据库,什么类型?
  • 在postgreSQL中是int4range

标签: ruby-on-rails postgresql activerecord


【解决方案1】:

我认为您需要在字符串中使用PostgreSQL range operators 和一些SQL。特别是,您需要 @&gt;(包含元素)运算符:

JobRequirement.where('age @> ?', 20)

就提供范围作为占位符值而言:

JobRequirement.where('age <@ ?', 18..20)

您会发现 AR 对 PostgreSQL 范围类型的了解有些有限。当您提供一个范围作为占位符的值时,AR 将希望将该范围扩展为一个逗号分隔的列表,因为它假设您在说类似 where('col in (?)', 18..20) 的内容,因此您最终会得到以下废话:

where age <@ 18,19,20

在生成的 SQL 中。您可以通过手动类型转换值来解决此问题;例如:

> ActiveRecord::Base.connection.type_cast(6..11)
 => "[6,11]" 
> ActiveRecord::Base.connection.type_cast(6...11)
 => "[6,11)" 

然后将字符串发送到 PostgreSQL 应该自动将其转换为 PostgreSQL 范围的查询中:

JobRequirement.where('age <@ ?', ActiveRecord::Base.connection.type_cast(18..20))

根据您执行此操作的位置,connection 方法可能适用于所有噪音:

JobRequirement.where('age <@ ?', connection.type_cast(18..20))

如果 PostgreSQL 没有自行选择正确版本的 &lt;@ 运算符,那么您可以帮助它进行更多类型转换:

JobRequirement.where('age <@ ?::int4range', connection.type_cast(18..20))

【讨论】:

  • Person.where('age &lt;@ ?', 18..20) 怎么样?我收到一个错误ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: operator does not exist: integer &lt;@ integer
猜你喜欢
  • 2015-11-28
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 2014-03-04
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
相关资源
最近更新 更多