Rails7/Devise项目数据库种子数据创建失败求助
Rails 7 + Devise-API 种子数据报错:SQLite3::SQLException: no such column: users.password
你在开发Rails7/React架构的简易POS系统,使用devise-api和devise-security实现认证与会话限制,执行数据库种子命令时出现如下错误:
rails aborted! ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: users.password /home/samity/Development/code/phase-5/burghers/burghers_pos/db/seeds.rb:6:in `<main>' Caused by: SQLite3::SQLException: no such column: users.password
你的相关代码如下:
User模型
# models/user.rb class User < ApplicationRecord has_many :checks, dependent: :destroy validates :password, presence: true, uniqueness: true validates :first_name, presence: true validates :last_name, presence: true devise :database_authenticatable, :registerable, :api, :recoverable, :rememberable, :validatable, :session_limitable end
数据库迁移文件
# db/migrate/devise_create_users.rb class DeviseCreateUsers < ActiveRecord::Migration[7.0] def change create_table :users do |t| t.string :first_name, null: false, default: "" t.string :last_name, null: false, default: "" t.string :encrypted_password, null: false, default: "" t.boolean :admin, null: false, default: false t.string :unique_session_id t.timestamps null: false end end
种子文件
# db/seeds.rb users = User.create!( [ { first_name: "John", last_name: "Smith", password: "1111", password_confirmation: "1111", admin: true }, { first_name: "Samuel", last_name: "Amity", password: "4000", password_confirmation: "4000", admin: false } ] )
问题原因
你在User模型里手动添加了validates :password, presence: true, uniqueness: true,其中uniqueness: true这个验证会让ActiveRecord直接去数据库的users表中查找password字段,但你的数据库里只有encrypted_password字段(Devise会自动处理明文密码到加密密码的转换,password是Devise提供的虚拟属性,不会存储到数据库),因此触发了这个报错。
另外,Devise的:validatable模块已经自带了密码的必填验证,你手动添加的presence: true其实是多余的。
解决方案
- 修改User模型,移除多余的密码验证:
# models/user.rb class User < ApplicationRecord has_many :checks, dependent: :destroy validates :first_name, presence: true validates :last_name, presence: true devise :database_authenticatable, :registerable, :api, :recoverable, :rememberable, :validatable, :session_limitable end
确保数据库迁移已正确执行(如果之前没跑过,先执行
rails db:migrate)重新运行种子数据命令:
rails db:seed
额外说明
如果你的需求是确保用户密码唯一,这个逻辑本身不建议实现:因为Devise会为每个密码生成随机盐值,即使两个用户使用相同的明文密码,最终存储的encrypted_password也是不同的,所以无法通过数据库层面验证密码唯一性,强行实现需要自定义逻辑对比明文密码,但这会带来安全风险(比如需要临时存储明文密码做对比),通常不推荐。
内容的提问来源于stack exchange,提问作者Samity
相关产品推荐
相关产品推荐

