Rails创建UUID主键表时出现NOT NULL约束失败问题求助
Rails SQLite使用UUID主键触发非空约束异常的解决方法
问题原因
SQLite本身没有内置的UUID自动生成机制,当你在迁移中指定id: :uuid时,仅会将主键字段类型设置为UUID,但不会自动为该字段生成默认值。插入数据时Rails未自动填充UUID(或填充失败),导致places.id为null,触发非空约束异常。
解决方案
方案1:修改迁移文件,添加SQLite兼容的UUID默认值
更新迁移文件,为id字段指定SQLite可执行的UUID生成语句作为默认值:
class AddPlacesTable < ActiveRecord::Migration[7.0] def change create_table :places, id: :uuid, default: -> { "hex(randomblob(4)) || '-' || hex(randomblob(2)) || '-' || '4' || substr(hex(randomblob(2)),2) || '-' || substr('89ab',abs(random())%4+1,1) || substr(hex(randomblob(2)),2) || '-' || hex(randomblob(6))" } do |t| t.string :name, null: false t.string :address, null: false t.string :city, null: false t.timestamps end end end
执行迁移后,SQLite会在插入数据时自动生成符合RFC4122标准的UUID作为主键值。
方案2:通过模型回调生成UUID
- 在Gemfile中添加
uuidtools依赖:
gem 'uuidtools'
执行bundle install安装依赖。
- 在
Place模型中添加before_create回调,手动生成UUID:
class Place < ApplicationRecord before_create :generate_uuid private def generate_uuid self.id = UUIDTools::UUID.random_create.to_s end end
这样每次创建新记录时,会在保存前自动生成UUID并赋值给id字段。
内容的提问来源于stack exchange,提问作者s-chuck
相关产品推荐
相关产品推荐

