Devise User模型新增字段后无法存库,RSpec测试报nil类无address方法错误
问题原因
- 多余的
attr_accessor覆盖了ActiveRecord的默认属性读写逻辑
如果username、address、first_name、last_name这几个字段已经通过数据库迁移添加到了users表中,完全不需要手动声明attr_accessor。手动添加的attr_accessor会覆盖ActiveRecord根据表结构自动生成的属性方法,导致这些字段的赋值只会保存在实例内存中,不会被持久化到数据库,即便创建成功后续查询也读不到对应值。 - Devise校验未通过导致创建失败
你启用了Devise的:validatable模块,该模块默认要求创建用户时必须传入password和password_confirmation两个必填字段,你的测试代码中调用User.create时没有传入密码相关字段,校验直接失败,自然不会生成数据库记录。你注释devise配置行后,:validatable模块也被同步禁用,校验规则消失,所以测试可以正常运行,该问题不是Devise的故障,是未满足Devise默认校验规则导致的。
修复方案
- 直接删除User模型中如下行代码:
attr_accessor :username, :first_name, :last_name, :address
- 修改测试代码的创建逻辑,补全必填的密码字段,建议使用
create!代替create,校验失败时会直接抛出异常,更方便定位问题:
before(:all) do User.create!( email: "test@gmail.com", address: "nyc", first_name: "aa", last_name: "bb", username: "lol", password: "123456", password_confirmation: "123456" ) end
- (可选)如果后续需要在注册、修改资料等接口中传入新增字段,需要在控制器层将这些字段添加到Devise的强参数允许列表中,模型层测试不需要处理该配置。
内容的提问来源于stack exchange,提问作者shengjiang
相关产品推荐
相关产品推荐

