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

Rails 7.0.6:注释所有Fixture仍触发外键约束违反错误

Rails测试外键错误排查与解决

问题概述

  • 测试运行时抛出错误:
    RuntimeError: Foreign key violations found in your fixture data. Ensure you aren't referring to labels that don't exist on associations.
    
  • 已注释所有Fixture文件,项目含4个模型(其中一个带Active Storage附件),所有表为空仍触发错误
  • 已尝试重建测试数据库、重新执行迁移,问题未解决
  • 最近代码变更:通过scaffold新增2个模型(其一带Active Storage附件)、修改某模型为自定义主键(该主键被另一模型引用)

Postgres日志(中文翻译)

2023-08-13 20:26:45.959 CEST [3596] ERROR:  权限拒绝:"RI_ConstraintTrigger_c_41320" 是系统触发器
2023-08-13 20:26:45.959 CEST [3596] STATEMENT:  ALTER TABLE "active_storage_variant_records" DISABLE TRIGGER ALL;ALTER TABLE "disbursements" DISABLE TRIGGER ALL;ALTER TABLE "merchants" DISABLE TRIGGER ALL;ALTER TABLE "merchants_files" DISABLE TRIGGER ALL;ALTER TABLE "orders" DISABLE TRIGGER ALL;ALTER TABLE "active_storage_blobs" DISABLE TRIGGER ALL;ALTER TABLE "active_storage_attachments" DISABLE TRIGGER ALL;ALTER TABLE "schema_migrations" DISABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" DISABLE TRIGGER ALL
2023-08-13 20:26:45.963 CEST [3596] ERROR:  权限拒绝:"RI_ConstraintTrigger_c_41320" 是系统触发器
2023-08-13 20:26:45.963 CEST [3596] STATEMENT:  ALTER TABLE "active_storage_variant_records" ENABLE TRIGGER ALL;ALTER TABLE "disbursements" ENABLE TRIGGER ALL;ALTER TABLE "merchants" ENABLE TRIGGER ALL;ALTER TABLE "merchants_files" ENABLE TRIGGER ALL;ALTER TABLE "orders" ENABLE TRIGGER ALL;ALTER TABLE "active_storage_blobs" ENABLE TRIGGER ALL;ALTER TABLE "active_storage_attachments" ENABLE TRIGGER ALL;ALTER TABLE "schema_migrations" ENABLE TRIGGER ALL;ALTER TABLE "ar_internal_metadata" ENABLE TRIGGER ALL
2023-08-13 20:26:45.966 CEST [3596] ERROR:  表 pg_constraint 权限拒绝
2023-08-13 20:26:45.966 CEST [3596] CONTEXT:  SQL语句 "UPDATE pg_constraint SET convalidated=false WHERE conname = 'fk_rails_c3b3935057' AND connamespace::regnamespace = 'public'::regnamespace; ALTER TABLE public.active_storage_attachments VALIDATE CONSTRAINT fk_rails_c3b3935057;"
    PL/pgSQL函数 inline_code_block 第16行 EXECUTE处
2023-08-13 20:26:45.966 CEST [3596] STATEMENT:  do $$
      declare r record;
    BEGIN
    FOR r IN (
      SELECT FORMAT(
        'UPDATE pg_constraint SET convalidated=false WHERE conname = ''%I'' AND connamespace::regnamespace = ''%I''::regnamespace; ALTER TABLE %I.%I VALIDATE CONSTRAINT %I;',
        constraint_name,
        table_schema,
        table_schema,
        table_name,
        constraint_name
      ) AS constraint_check
      FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY'
    )
      LOOP
        EXECUTE (r.constraint_check);
      END LOOP;
    END;
    $$;

解决步骤

1. 修复数据库用户权限

日志明确显示测试数据库用户无操作系统触发器和pg_constraint表的权限,执行以下操作:

  • 登录Postgres超级用户(如postgres),运行SQL:
    GRANT ALL PRIVILEGES ON DATABASE your_test_db_name TO your_app_user;
    GRANT ALL ON SCHEMA public TO your_app_user;
    GRANT ALL ON ALL TABLES IN SCHEMA public TO your_app_user;
    GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO your_app_user;
    
  • 本地开发环境可直接修改config/database.yml,将测试库用户名改为postgres(超级用户),避免权限问题。

2. 检查自定义主键的外键关联

修改模型为自定义主键后,需确保关联字段完全匹配:

  • 确认关联模型的外键字段类型与自定义主键类型一致(比如主键是字符串,外键不能用默认的bigint),检查迁移文件是否明确指定类型。
  • 回滚并重新执行迁移:
    rails db:rollback STEP=2  # 回滚到修改主键前的版本,步数按需调整
    rails db:migrate
    rails db:test:prepare
    

3. 清理Active Storage关联残留

新增带Active Storage的模型后,可能存在无效约束:

  • 检查db/schema.rb中active_storage_attachments和active_storage_blobs的外键约束是否合法。
  • 权限修复后仍有问题,可手动删除无效约束:
    ALTER TABLE active_storage_attachments DROP CONSTRAINT IF EXISTS fk_rails_c3b3935057;
    

4. 临时禁用测试外键校验

若以上步骤无效,可在测试环境临时禁用外键校验:

  • 在test/test_helper.rb中添加:
    class ActiveSupport::TestCase
      setup do
        ActiveRecord::Base.connection.disable_referential_integrity {}
      end
    end
    

内容的提问来源于stack exchange,提问作者Sergey Panov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:10:58