如何在Rails-Postgres迁移中添加UPDATE CASCADE?

时间:2015-08-28 19:59:13

标签: sql ruby-on-rails postgresql foreign-keys rails-migrations

我需要编写一个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来处理这个?

1 个答案:

答案 0 :(得分:3)

据推测,您的迁移中某处有t.referencest.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约束,那么我认为您需要手动修复:

  1. 添加迁移以删除原始约束并添加更新的约束:

    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选择的约束名称,但您也可以。

  2. 手动修改db/schema.rb,将上述:foreign_key => { :on_update => :cascade }添加到相应的t.references来电。