Tag*_*ag0 4 sql postgresql ruby-on-rails foreign-keys rails-migrations
我需要编写一个Rails迁移,该迁移将更新特定对象的uuid,然后通过将该ID作为外键存储的所有行进行CASCADE,如下所示:
alter table projects add constraint fk_league
foreign key (user_id) references users(id) on update cascade
Run Code Online (Sandbox Code Playgroud)
不幸的是,Rails似乎会自动生成约束:
fk_rails_e4348431a9
Run Code Online (Sandbox Code Playgroud)
我将如何编写上述sql来处理此问题?
大概您的迁移中有一个t.references或t.belongs_to某处:
t.references :user, :foreign_key => true
Run Code Online (Sandbox Code Playgroud)
这t.references只是add_reference变相的电话。该add_reference文档没有说明有关该:foreign_key选项的值的任何有用信息,但是代码可以:
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
Run Code Online (Sandbox Code Playgroud)
因此,当您指定:foreign_key选项时,可以将其传递给基础add_foreign_key调用的选项哈希,并且具有一个:on_update选项:
:on_update
发生的动作ON UPDATE。有效值为:nullify,:cascade:[sic]和:restrict
您想将原始t.references通话替换为以下内容:
t.references :user, :foreign_key => { :on_update => :cascade }
Run Code Online (Sandbox Code Playgroud)
如果您已经在生产中进行了所有设置,并且需要更改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
Run Code Online (Sandbox Code Playgroud)
您可能不需要保留Rails选择的约束名称,但是您也可以保留。
手动进行编辑,db/schema.rb以将上述内容添加:foreign_key => { :on_update => :cascade }到相应的t.references呼叫中。