Rails:在添加列后添加索引


119

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

rails generate migration AddUser_idColumnToTable user_id:string. 

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

Answers:


235

您可以仅针对索引运行另一个迁移:

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

4
因此,我只在控制台中运行:rails生成迁移AddIndexToTable吗?
user1611830 2013年

3
是的,您可以这样做,但是之后必须编辑该迁移以反映上述代码。
Jaap Haagmans

:table应该是复数吗?

1
@tomb我使用原始问题中的示例。:table是实际的表名,所以在的情况users表,你会替代:users:table
Jaap Haagmans

65

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

rails generate migration AddUserRefToProducts user:references

此命令将生成以下迁移:

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

运行后rake db:migrateuser_id列和索引将被添加到products表中。

如果你只需要一个索引添加到现有的塔,例如name一的user表,下面的技术可能会有所帮助:

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

感谢Vadym的完整答案。最后一个问题:为什么您建议撤消初始迁移?以后是否存在与添加索引相关的性能问题?
Flavio Wuensche 2015年

2
致@fwuensche:以后添加索引不会降低性能。但是,域逻辑将不太清楚。例如,如果您以后决定断开/抽象/等关联,则需要处理两个单独的迁移,这实际上应该是一个迁移...
Vadym Tyemirov

5
警告:请注意,index:true仅在create_table迁移中有效。迁移将运行,但不会创建索引。见makandracards.com/makandra/...
rmcsharry

9

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

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

你的意思是这样的:def self.up add_column ... end add_index ...?
user1611830 2013年

5

有关参考,您可以致电

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

0

您可以使用它,只是认为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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.