Ruby on Rails项目中如何将UUID作为非主键普通列使用
这个需求完全可实现,Ruby on Rails对UUID字段的支持不绑定主键配置,你完全可以在保留原有默认自增主键的前提下,给表新增独立的UUID普通列,适配PostgreSQL、MySQL 8.0+等主流数据库。
前置准备:启用数据库UUID能力
以最常用的PostgreSQL为例,需要先启用pgcrypto扩展获得数据库层面的UUID生成能力,先生成对应迁移文件:rails generate migration EnableUuidExtension编辑生成的迁移文件内容:
class EnableUuidExtension < ActiveRecord::Migration[7.1] # 替换为你项目实际的Rails版本号 def change enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto') end end执行
rails db:migrate完成扩展启用。如果你用的是MySQL 8.0+,不需要额外启用扩展,直接支持UUID生成函数。
给Address表新增UUID普通列
生成字段添加的迁移文件:rails generate migration AddUuidToAddresses uuid:uuid编辑迁移文件,配置数据库自动生成UUID、添加唯一索引,注意不要修改原有主键配置:
class AddUuidToAddresses < ActiveRecord::Migration[7.1] def change add_column :addresses, :uuid, :uuid, default: -> { "gen_random_uuid()" }, null: false add_index :addresses, :uuid, unique: true # 数据库层保证UUID不重复 end end执行
rails db:migrate完成字段添加。这一步完成后,新建Address记录时数据库会自动给uuid字段填充随机UUID,不需要手动赋值,原有默认的id主键逻辑完全不受影响。MySQL用户注意:如果追求存储查询性能,可以将字段类型设为
binary(16),默认值配置为-> { "(UUID_TO_BIN(UUID()))" };如果不需要极致性能,直接用char/varchar类型存36位字符串格式UUID也可正常使用。模型层可选配置
你可以根据业务需求在Address模型中添加对应校验,或者配置对外暴露的查找逻辑,避免把自增主键ID暴露给外部系统:class Address < ApplicationRecord # 基础校验,和数据库唯一索引形成双重保障 validates :uuid, presence: true, uniqueness: true # 可选:对外接口统一用UUID查找,替换默认的id参数返回逻辑 # def to_param # uuid # end end
不要在表创建/修改迁移中添加id: :uuid配置,该配置的作用是将表的主键替换为UUID类型,和本次新增普通UUID列的需求无关。
内容的提问来源于stack exchange,提问作者Vinicius Köhler

