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

Rails自关联迁移使用strong_migrations时外键正常配置问题

你需要拆分出额外的迁移单独处理外键约束,完整操作流程如下:

步骤1:执行现有引用添加迁移

你当前编写的添加master引用并并发创建索引的迁移是正确的,先运行该迁移完成字段和索引的创建:

class AddMasterToOrganizations < ActiveRecord::Migration[6.1]
  disable_ddl_transaction!

  def change
    add_reference :organizations, :master, index: {algorithm: :concurrently}
  end
end

步骤2:新增迁移添加外键约束

单独创建迁移来添加自关联外键,生产环境大表建议先添加不验证存量数据的外键,避免长时间锁表阻塞业务:

class AddMasterForeignKeyToOrganizations < ActiveRecord::Migration[6.1]
  disable_ddl_transaction!

  def change
    add_foreign_key :organizations, :organizations, column: :master_id, validate: false
  end
end

步骤3(可选,针对有存量数据的表):验证外键约束

如果你的organizations表已有存量数据,先核对所有非空的master_id都对应存在的organizations记录,再新增迁移完成外键验证:

class ValidateMasterForeignKeyOnOrganizations < ActiveRecord::Migration[6.1]
  def change
    validate_foreign_key :organizations, :master_id
  end
end

模型层关联配置

完成迁移后需要在Organization模型中添加对应关联,才能实现你要的调用效果:

class Organization < ApplicationRecord
  # 主记录关联对应的草稿
  has_one :draft, class_name: 'Organization', foreign_key: 'master_id'
  # 草稿关联对应的主记录,设置optional是因为主记录本身不需要填写master_id
  belongs_to :master, class_name: 'Organization', optional: true
end

配置完成后即可正常调用main_record.draft获取对应草稿,调用draft_record.master获取对应主记录。

原理说明

strong_migrations不支持在同一迁移中同时执行并发索引创建和外键添加:并发创建索引不能在事务中运行,而外键添加默认会开启事务,二者放在同一迁移会产生冲突。拆分迁移的写法是生产环境大表修改的标准方案,不会产生长时间锁表问题。

内容的提问来源于stack exchange,提问作者Jack Walsh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:45:07