Rails测试遇ActiveRecord::NotNullViolation:created_at非空约束失败
Rails Fixtures 自动填充 created_at 失败问题解决
使用 Ruby 3.3.3 + Rails 7.1.3.4 进行测试时,触发错误:ActiveRecord::NotNullViolation: RuntimeError: NOT NULL constraint failed: drives.created_at。根据 ActiveRecord 文档,Fixtures 应自动填充 created_at 字段,但当前项目无法实现该功能,干净的 Rails 环境中则正常运行。
相关代码与日志
Drive 模型代码
class Drive < ApplicationRecord with_options presence: true do validates :name validates :provider validates :credentials end encrypts :credentials end
迁移文件代码
class CreateDrives < ActiveRecord::Migration[7.1] def change create_table :drives do |t| t.string :name t.string :provider t.text :credentials t.timestamps end end end
Fixtures 代码
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: name: MyString provider: MyString credentials: MyText two: name: MyString provider: MyString credentials: MyText
测试日志片段
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m [1m[36mFixtures Load (0.2ms)[0m [1m[31mDELETE FROM "drives"; INSERT INTO "drives" ("name", "provider", "credentials") VALUES ('MyString', 'MyString', 'MyText'); INSERT INTO "drives" ("name", "provider", "credentials") VALUES ('MyString', 'MyString', 'MyText')[0m [1m[36mTRANSACTION (0.0ms)[0m [1m[31mrollback transaction[0m
排查与解决步骤
检查 Fixture 全局配置
查看test_helper.rb或config/application.rb,确认是否存在禁用自动时间戳填充的配置:# 若存在此行需移除 ActiveRecord::FixtureSet.enable_transactional_fixtures = false验证模型时间戳设置
检查 Drive 模型是否禁用了自动时间戳记录,若有如下代码需移除:self.record_timestamps = false # 或 self.ignored_columns = [:created_at, :updated_at]排查加密字段干扰
临时注释掉模型中的encrypts :credentials配置,重新运行测试。若恢复正常,需确认加密逻辑未修改模型初始化流程,可尝试更新 Rails 加密相关依赖或调整加密配置。手动指定时间戳(临时方案)
若以上方法无效,可在 Fixtures 文件中手动添加时间戳字段:one: name: MyString provider: MyString credentials: MyText created_at: <%= Time.now %> updated_at: <%= Time.now %> two: name: MyString provider: MyString credentials: MyText created_at: <%= Time.now %> updated_at: <%= Time.now %>重置测试数据库
执行以下命令确保测试数据库迁移正确:rails db:test:prepare
内容的提问来源于stack exchange,提问作者Ghassen Rjab
相关产品推荐
相关产品推荐

