You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:52:18