5
votes

I've just upgraded an old app from Rails 3.0 to 4.2 and now it is impossible to query the database for very long IDs.

Rails 3

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

Rails 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'

I'd expect that the finder returns nothing in Rails 4.2.3 as well in such a case. It's just searching for results, we don't need to call ensure_in_range.

UPDATE: however, the following works fine (it may serve as a workaround):

Product.find_by(associated_id: 1311344470881970878875083923)

It works because find_by is implemented as below:

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

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

Unfortunately a similar method for returning all results is missing in ActiveRecord 4.2.3

def find_all_by(*args)
  where(*args).load
rescue RangeError
  none
end
1
thats a pretty big number for an integer! - Tim Kretschmer

1 Answers

-1
votes

1311344470881970878875083923 ist way out of the INT Range in postgres. Every Datatype has its own range. a Integer normally presenting 4 bytes, which means there are 4294967294 different values. (-2147483647 till +2147483647 and a 0).

if you need those big numbers as the object_id, make sure to use a bigint. he can handle those.

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

edit

as on your edit, you can extend your ActiveRecord with ease

# config/initializer/active_record.rb

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