【问题标题】:RangeError when querying for big number using #where in Rails 4.2在 Rails 4.2 中使用#where 查询大数时出现 RangeError
【发布时间】:2015-11-14 00:28:14
【问题描述】:

我刚刚将一个旧应用从 Rails 3.0 升级到 4.2,现在无法在数据库中查询很长的 ID。

导轨 3

Product.where(associated_id: 1311344470881970878875083923).first
=> nil

导轨 4.2.3

Product.where(associated_id: 1311344470881970878875083923).first
RangeError: 1311344470881970878875083923 is out of range for ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer with limit 8
from ~/.rvm/gems/ruby-2.2.1@gemset/gems/activerecord-4.2.3/lib/active_record/type/integer.rb:45:in `ensure_in_range'

在这种情况下,我希望查找器在 Rails 4.2.3 中也不会返回任何内容。只是搜索结果,我们不需要调用ensure_in_range

更新:但是,以下工作正常(它可以作为一种解决方法):

Product.find_by(associated_id: 1311344470881970878875083923)

之所以有效,是因为find_by 的实现方式如下:

def find_by(*args)
  where(*args).take
rescue RangeError
  nil
end

http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find_by

不幸的是,ActiveRecord 4.2.3 中缺少用于返回所有结果的类似方法

def find_all_by(*args)
  where(*args).load
rescue RangeError
  none
end

【问题讨论】:

  • 对于整数来说这是一个相当大的数字!

标签: ruby-on-rails-4 activerecord ruby-on-rails-4.2


【解决方案1】:

1311344470881970878875083923 在 postgres 中超出 INT 范围。 每个数据类型都有自己的范围。一个整数,通常表示 4 个字节,这意味着有 4294967294 个不同的值。 (-2147483647 到 +2147483647 和 0)。

如果您需要这些大数字作为 object_id,请确保使用 bigint。他可以处理这些。

http://www.postgresql.org/docs/9.3/static/datatype-numeric.html

编辑

在您的编辑中,您可以轻松扩展 ActiveRecord

# config/initializer/active_record.rb

class ActiveRecord::Base     
  def self.find_all_by(*args)
      where(*args).load
    rescue RangeError
      nil
  end
end

【讨论】:

  • 这真的没有给这个讨论带来任何东西。请参阅我的第一篇文章中的“更新”部分。我们真正缺少的是 find_all_by 之类的东西。不管我向这个查询发送什么样的数字,当我只想在数据库中查找某些东西时,它不应该因为这样的错误而失败。
  • 那么为什么不实现自己的“find_all”方法呢?
  • 当然我可以用我的方法扩展AR。我正在寻找一些关于使用未经修改的 AR 实现它的提示。
猜你喜欢
  • 1970-01-01
  • 2022-12-14
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多