Rails: 添加列后添加索引

假设我在一个 Rails 应用程序中创建了一个表 table,过了一段时间,我添加了一个运行:

rails generate migration AddUser_idColumnToTable user_id:string.

然后我意识到我需要添加 user_id作为索引。我知道 add_index方法,但是应该在哪里调用这个方法呢?我是否应该运行迁移(如果是,哪一个?)然后手工添加这个方法?

153563 次浏览

您可以为索引运行另一个迁移:

class AddIndexToTable < ActiveRecord::Migration
def change
add_index :table, :user_id
end
end

在创建列之后添加生成的迁移以下内容(示例)

add_index :photographers, :email, :unique => true

如果您需要创建一个 user_id,那么可以合理地假设您正在引用一个用户表。在这种情况下,迁移应:

rails generate migration AddUserRefToProducts user:references

该命令将生成以下迁移:

class AddUserRefToProducts < ActiveRecord::Migration
def change
add_reference :user, :product, index: true
end
end

在运行 rake db:migrate之后,user_id列和索引都将被添加到 products表中。

如果您只是需要向现有列添加一个索引,例如 user表的 name,以下技术可能会有所帮助:

rails generate migration AddIndexToUsers name:string:index将产生以下迁移:

class AddIndexToUsers < ActiveRecord::Migration
def change
add_column :users, :name, :string
add_index :users, :name
end
end

删除 add_column行并运行迁移。

在上述情况下,您可以发出 rails generate migration AddIndexIdToTable index_id:integer:index命令,然后从生成的迁移中删除 add_column行。但我建议撤消初始迁移并添加引用:

rails generate migration RemoveUserIdFromProducts user_id:integer
rails generate migration AddUserRefToProducts user:references

你可以打电话给

rails generate migration AddUserIdColumnToTable user:references

如果将来需要添加一个通用索引,可以启动这个

rails g migration AddOrdinationNumberToTable ordination_number:integer:index

生成的代码:

class AddOrdinationNumberToTable < ActiveRecord::Migration
def change
add_column :tables, :ordination_number, :integer
add_index :tables, :ordination_number, unique: true
end
end

您可以使用它,只要想想 Job 是您要添加索引 Cader _ id的模型的名称:

class AddCaderIdToJob < ActiveRecord::Migration[5.2]
def change
change_table :jobs do |t|
t.integer :cader_id
t.index :cader_id
end
end
end

对于那些使用 postgreqldb 并面临错误的用户

StandardError: An error has occurred, this and all later migrations canceled:


=== Dangerous operation detected #strong_migrations ===


Adding an index non-concurrently blocks writes

请参阅 这篇文章

例如:

class AddAncestryToWasteCodes < ActiveRecord::Migration[6.0]
disable_ddl_transaction!


def change
add_column :waste_codes, :ancestry, :string
add_index :waste_codes, :ancestry, algorithm: :concurrently
end
end