Rails 5.2+PostgreSQL环境下特定模型创建后未返回生成ID如何解决
根因定位
问题根源在invoices表的schema定义上:
create_table "invoices", id: false, force: :cascade do |t|
这里显式添加的id: false参数,会告诉Rails该表不需要自动生成主键,即使后续手动添加了serial类型的id列,Rails也不会自动将这个列识别为表的主键,自然不会在INSERT语句后拼接RETURNING "id"来获取数据库生成的主键值。
而运行正常的customers表使用的是id: :serial配置,Rails会自动把id列识别为主键,插入操作完成后会自动返回ID值。
修复方案
两种修复方式可根据实际场景选择:
方式1:修改表定义(推荐)
如果id列确实是业务使用的主键,直接把create_table的id: false参数删除,调整为和customers表一致的配置即可:
create_table "invoices", id: :serial, force: :cascade do |t| # 需删除手动定义的t.serial "id", null: false行,Rails会自动生成主键列 t.float "amount" t.datetime "created_at" t.datetime "updated_at" end
生成对应迁移脚本后执行即可生效。
方式2:显式指定模型主键
如果因历史遗留问题不能修改表结构,直接在Invoice模型中手动指定主键列即可:
class Invoice < ActiveRecord::Base self.primary_key = 'id' end
添加该配置后,Rails就会将id列识别为主键,插入语句会自动拼接RETURNING "id",保存完成后就能正常获取到id值。
验证方法
修改完成后在rails console中执行Invoice.create(amount: 12.34),观察到INSERT语句已经带上RETURNING子句、返回的实例id不为null,即说明修复成功。
内容的提问来源于stack exchange,提问作者Gavin Morris
相关产品推荐
相关产品推荐

