Rails 3.1.0迁移中的remove_index的正确语法是什么?

我正在将Devise添加到现有的Rails应用程序中,并且已经定义了Users表。 devise生成器推出了以下迁移:

class AddDeviseToUsers < ActiveRecord::Migration def self.up change_table(:users) do |t| ## Database authenticatable t.string :email, :null => false, :default => "" t.string :encrypted_password, :null => false, :default => "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at ## Trackable t.integer :sign_in_count, :default => 0 blah blah blah.... end add_index :users, :email, :unique => true add_index :users, :reset_password_token, :unique => true end 

没有生成向下的迁移,我正在删除这些索引。 我在文档中看到了不同的build议符号,并在网上提出了不同的build议,但是他们都没有为我工作。 例如…

 def self.down change_table(:users) do |t| t.remove :email t.remove :encrypted_password t.remove :reset_password_token blah blah blah... end remove_index :users, :email remove_index :users, :reset_password_token end 

结果是…

 An error has occurred, this and all later migrations canceled: Index name 'index_users_on_email' on table 'users' does not exist 

这很奇怪,因为如果我检查数据库,果然,'index_users_on_email'就在那里…

我试过其他的变化,包括

 remove_index :users, :column => :email remove_index :users, 'email' 

要么:

 change_table(:users) do |t| t.remove_index :email end 

…但没有骰子。 我正在使用Postgres运行Rails 3.1.0,Ruby 1.9.2,rake 0.9.2.2。

让我失望的命令是:

 bundle exec rake db:rollback STEP=1 

成功申请迁移后。 有什么build议?

根据数据库types,您不必担心删除self.down方法中的索引,因为删除列时索引将自动从数据库中删除。

你也可以在self.down方法中使用这个语法:

 def self.down remove_column :users, :email remove_column :users, :encrypted_password remove_column :users, :reset_password_token end 

为了logging,按名称删除索引的方式是

 remove_index(:table_name, :name => 'index_name') 

所以在你的情况

 remove_index(:users, :name => 'index_users_on_email') 

你也可以删除指定列的索引,从我的angular度来看,比写名字更容易出错

 remove_index :actions, :column => [:user_id, :action_name] 

我想扩展@ iWasRobbed的答案。 如果你只有一列的索引,那么担心remove_index是没有意义的,因为(只是一个假设!)数据库应该足够聪明来清理该索引使用的资源。 但万一你有多列索引删除列会减less索引到仍然存在的列,这是完全明智的事情要做,但种显示你可能想要使用remove_index明确。

只是为了说明 – 下面的迁移有这样的缺陷,上下应用会留下唯一的email索引(意思是说down部分没有做好它的工作)

 class AddIndexes < ActiveRecord::Migration def up add_column :users, :action_name, :string add_index :users, [:email, :action_name], unique: true end def down remove_column :users, :action_name end end 

down块更改为

  def down remove_index :users, [:email, :action_name] remove_column :users, :action_name end 

将修复该缺陷,并允许迁移使用rake db:rollback正确地返回到以前的状态

要改变表格和/或其#change_table#change动作中使用#change_table 。 那么你可以创build可逆的索引删除,如下所示:

 def change change_table :users do |t| t.index :email, :unique => true t.index :reset_password_token, :unique => true end end 

当你必须使用#drop_table动作的索引来删除一个表时,你可以使用#drop_table#index方法和ConnectionAdapterTable类的#index方法:

 def change drop_table :users do |t| t.index :email, :unique => true t.index :reset_password_token, :unique => true end end 

如果你在迁移中需要完全的#up/down对。 对于ConnectionAdapter只使用#remove_index方法和Table类的#remove_index方法:

 def up change_table :users do |t| t.index :email, :unique => true t.index :reset_password_token, :unique => true end end def down change_table :users do |t| t.remove_index :email, :unique => true t.remove_index :reset_password_token, :unique => true end end 

所有的方法都可以在Rails 2.1.0或更早的版本中find。

这是我完整的运行(在Rails 5中):

我有team_id作为表供应商的索引。 我不再需要这种关系。 摆脱它。 有以下几点:

1)创build迁移。

  $ rails generate migration RemoveTeam_idFromVendor team_id:integer 

2)运行迁移,给我这个错误。 这是因为供应商表具有其外键引用组表的主键值的行

 == 20170727202815 RemoveTeamIdFromVendor: migrating =========================== -- remove_column(:vendors, :team_id, :integer) rake aborted! StandardError: An error has occurred, this and all later migrations canceled: SQLite3::ConstraintException: FOREIGN KEY constraint failed: DROP TABLE "vendors" 

3)为了解决这个问题,让迁移运行,我做了以下(注:我在开发中):

 $ rake db:drop Dropped database 'db/development.sqlite3' Dropped database 'db/test.sqlite3' $ rake db:create Created database 'db/development.sqlite3' Created database 'db/test.sqlite3' $ rake db:migrate ~ ~ ~ == 20170727202815 RemoveTeamIdFromVendor: migrating =========================== -- remove_column(:vendors, :team_id, :integer) -> 0.0185s == 20170727202815 RemoveTeamIdFromVendor: migrated (0.0185s) ==================