如何在Rails中从数据库列中删除唯一约束?

38

我使用以下迁移创建了一个表:

class CreateProfilePictures < ActiveRecord::Migration
  def change
    create_table :profile_pictures do |t|
      t.integer :user_id, null: false
      t.integer :picture_id, null: false
      t.timestamps null: false
    end

    add_index :profile_pictures, :user_id, unique: true
    add_index :profile_pictures, :picture_id, unique: true
  end
end

我尝试使用以下方法去除约束:

class FixProfilePic < ActiveRecord::Migration
  def change
    change_column :profile_pictures, :picture_id, :integer, unique: false
  end
end

如果我尝试在多个地方使用相同的picture_id,仍会出现唯一约束冲突错误。如何正确地删除picture_id的唯一性约束?


你需要移除 index - Pavan
4个回答

69

您必须使用以下代码删除索引:

remove_index :profile_pictures, :picture_id

然后使用以下方式再次添加它:

add_index :profile_pictures, :picture_id

ActiveRecord::Migration


1
这已经不再适用了。现在有效的是:remove_index :profile_pictures, name: 'picture_id' - Jason Swett
2
注意,此迁移的回滚不会恢复唯一约束。 - Andreas Baumgart

15

接受的答案存在问题:回滚操作无法正确执行,因为唯一索引未被恢复。

您可以尝试以下方法:

reversible do |dir|
  dir.up do
    remove_index :profile_pictures, :picture_id
    add_index :profile_pictures, :picture_id
  end

  dir.down do
    remove_index :profile_pictures, :picture_id
    add_index :profile_pictures, :picture_id, unique: true
  end
end

2
我已经接受这个作为新答案。 - Daniel

11

将索引修改为:

add_index :profile_pictures, :picture_id, unique: true

所以请更新您的索引:

  remove_index :profile_pictures, :picture_id
  add_index :profile_pictures, :picture_id

我猜这就是它。


1
为了使迁移可逆,现在(Rails 6+)需要使用:column选项。
添加unique: true还可以确保回滚迁移将重新创建具有唯一性约束的索引(除非同时插入了有问题的数据)。
  remove_index :profile_pictures, column: :picture_id, unique: true
  add_index :profile_pictures, :picture_id

还有一件事需要注意:如果你的表很大,那么在其上创建新索引可能会锁定对它的写入很长一段时间。如果你使用的是Postgres,请考虑使用algorithm: :concurrently


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接