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
相关产品推荐
相关产品推荐

