我需要编写一个Rails迁移,它将更新特定对象的uuid,然后CASCADE通过存储该id作为外键的所有行,如下所示:
alter table projects add constraint fk_league
foreign key (user_id) references users(id) on update cascade
不幸的是,Rails似乎会自动生成约束:
fk_rails_e4348431a9
我如何编写上面的sql来处理这个?
答案 0 :(得分:3)
据推测,您的迁移中某处有t.references
或t.belongs_to
:
t.references :user, :foreign_key => true
t.references
只是伪装的add_reference
电话。 add_reference
文档没有说明:foreign_key
选项的值有用,但the code会这样做:
foreign_key_options = options.delete(:foreign_key)
#...
if foreign_key_options
to_table = Base.pluralize_table_names ? ref_name.to_s.pluralize : ref_name
add_foreign_key(table_name, to_table, foreign_key_options.is_a?(Hash) ? foreign_key_options : {})
end
因此,当您指定:foreign_key
选项时,您可以为基础add_foreign_key
调用提供一个Hash of options并且具有:on_update
选项:
:on_update
发生的行动ON UPDATE
。有效值为:nullify
,:cascade:
[sic]和:restrict
您希望将原来的t.references
来电替换为更像这样的内容:
t.references :user, :foreign_key => { :on_update => :cascade }
如果您已经在生产中设置了所有内容并且需要更改FK约束,那么我认为您需要手动修复:
添加迁移以删除原始约束并添加更新的约束:
def up
connection.execute(%q{
alter table projects
drop constraint fk_rails_e4348431a9
})
connection.execute(%q{
alter table projects
add constraint fk_rails_e4348431a9
foreign key (user_id)
references users(id)
on update cascade
})
end
def down
# The opposite of the above...
end
您可能不需要保留Rails选择的约束名称,但您也可以。
手动修改db/schema.rb
,将上述:foreign_key => { :on_update => :cascade }
添加到相应的t.references
来电。