Rails中如何将Devise生成的默认主键替换为自定义User_ID字段
Devise自定义主键替换操作步骤
1. 编写数据库迁移
首先生成主键调整的迁移文件:rails generate migration ReplaceDefaultPrimaryKeyForUsers
打开生成的迁移文件(路径为db/migrate/[对应时间戳]_replace_default_primary_key_for_users.rb),写入以下逻辑,注意匹配你自己的Rails版本号:
class ReplaceDefaultPrimaryKeyForUsers < ActiveRecord::Migration[7.1] def up # 移除devise默认生成的id主键 remove_column :users, :id, :bigint if column_exists?(:users, :id) # 如果你还没创建自定义字段,用下面这行新增user_id并设为主键 add_column :users, :user_id, :bigint, null: false, primary_key: true # 如果你已经创建了user_id字段,把上面add_column换成下面这行 # change_column :users, :user_id, :bigint, null: false, primary_key: true # PostgreSQL下配置主键自增序列 execute "CREATE SEQUENCE IF NOT EXISTS users_user_id_seq OWNED BY users.user_id;" execute "ALTER TABLE users ALTER COLUMN user_id SET DEFAULT nextval('users_user_id_seq');" end def down # 回滚逻辑 remove_column :users, :user_id add_column :users, :id, :bigint, null: false, primary_key: true execute "CREATE SEQUENCE IF NOT EXISTS users_id_seq OWNED BY users.id;" execute "ALTER TABLE users ALTER COLUMN id SET DEFAULT nextval('users_id_seq');" end end
注意:不要使用驼峰格式的
User_ID作为字段名,PostgreSQL默认会将未加双引号的标识符转为全小写,后续查询会频繁出现字段不匹配问题,统一使用小写下划线分割的user_id即可。
执行迁移前务必备份数据库,避免数据丢失。
编辑完成后执行迁移命令:rails db:migrate
2. 修改User模型配置
打开app/models/user.rb,显式指定模型主键为自定义的user_id,原有devise相关配置不需要改动:
class User < ApplicationRecord # 新增这行指定自定义主键 self.primary_key = 'user_id' # 原有devise配置保持不变即可 devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable end
3. 调整Devise路由配置
打开config/routes.rb,在devise路由配置中指定主键参数,避免devise默认查找id字段报错:
Rails.application.routes.draw do devise_for :users, defaults: { id: :user_id } # 其余业务路由保持原有配置即可 end
注意事项
- 所有关联User模型的其他表,原有外键字段
user_id不需要调整,ActiveRecord会自动匹配新的主键关联关系 - 业务代码中
User.find(params[:id])这类写法不需要修改,ORM会自动映射到user_id字段查询 - 如果重写了Devise自带的控制器/视图,不要硬编码读取id字段,保持使用通用参数名即可
内容的提问来源于stack exchange,提问作者Abu Bakar
相关产品推荐
相关产品推荐

