Rails5+Ruby2.4.0运行rails test报Mysql2字段非空错误求助
解决Rails测试中
Mysql2::Error: Column 'encrypted_password' cannot be null错误 我来帮你搞定这个问题!你遇到的这个错误,核心原因是Fixture里的encrypted_password字段没有生成有效取值,导致测试时这条记录的该字段为空,触发了数据库的非空约束。
错误根源
你的users.yml里用了<% Devise::Encryptor.digest(User, 'password') %>,但这里犯了一个ERB语法的小错误:<% ... %>是执行代码但不输出结果的标签,所以YAML里的encrypted_password实际上是空值。另外,Fixture加载时如果模型初始化不完整,也可能导致Devise加密方法无法正常返回值,但最直接的问题还是ERB标签的写法。
解决方案
这里给你两个可行的解决办法,选一个适合你的就行:
方案1:修正ERB标签写法(推荐)
把Fixture里的<%改成<%=,这样ERB才会把加密后的密码值输出到YAML中:
admin: id: 1 first_name: admin last_name: tukaweb email: 'admin@email.com' encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %> regular: id: 2 first_name: vidur last_name: punj email: 'vidur.punj@hotmail.com' encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>
方案2:手动生成加密密码
如果ERB执行还是有问题,可以先在Rails控制台生成加密密码,再复制到Fixture里:
- 打开Rails控制台:
rails c - 执行命令生成加密密码:
Devise::Encryptor.digest(User, 'password') - 把输出的长哈希字符串复制到
users.yml的encrypted_password字段,替换原来的ERB代码。
额外验证步骤
- 运行测试前,先确保测试数据库结构正确:
rails db:test:prepare(Rails 5中这个命令会同步开发环境的数据库结构,并重新加载Fixture) - 确认你的
User模型里encrypted_password字段确实存在,且数据库中该字段设置了NOT NULL约束(Devise默认会添加这个约束)
内容的提问来源于stack exchange,提问作者vidur punj
相关产品推荐
相关产品推荐

