ActiveModel::Type::Integer最大取值咨询(Rails5.2+Postgres9.6)
问题解答
你遇到的问题核心是混淆了有符号和无符号4字节整数的范围。
你的计算2³² = 4294967296对应的是无符号32位整数的总取值数(范围0到4294967295),但Rails的ActiveModel::Type::Integer默认使用的是有符号4字节整数,对应Postgres 9.6中的integer类型。
有符号32位整数的取值范围是:-2³¹ 到 2³¹ - 1,也就是 -2147483648 到 2147483647——这就是你这个ID字段能存储的最大整数(2147483647)。你的数字3980040429显然超过了这个上限,所以触发了RangeError。
如果需要存储像3980040429这样更大的整数,你需要把字段类型改成8字节的bigint(对应Postgres的bigint类型,Rails中用:bigint)。bigint的范围是 -9223372036854775808 到 9223372036854775807,完全能容纳你的目标数字。
迁移示例(修改现有字段)
如果是修改已有的ID字段,可以创建这样的迁移:
class ChangeIdToBigint < ActiveRecord::Migration[5.2] def change # 替换your_table_name为你的表名 change_column :your_table_name, :id, :bigint # 如果是自增主键,确保保留自增特性(Postgres下bigint对应bigserial) execute "ALTER SEQUENCE your_table_name_id_seq AS bigint" end end
如果是新建表,直接在创建时指定主键类型:
class CreateYourTable < ActiveRecord::Migration[5.2] def change create_table :your_table_name, id: :bigint do |t| # 其他字段定义 end end end
内容的提问来源于stack exchange,提问作者Fellow Stranger
相关产品推荐
相关产品推荐

