2013-04-08 120 views
65

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

rails generate migration AddUser_idColumnToTable user_id:string. 

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

回答

147

您可以运行另一迁移,只为指数:

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

所以我只是在我的控制台中运行:rails生成迁移AddIndexToTable? – user1611830 2013-04-08 14:32:48

+1

是的,您可以这样做,但您必须事后编辑该迁移以反映上述代码。 – 2013-04-08 14:33:26

+0

是的,谢谢! – user1611830 2013-04-08 14:34:15

7

添加在生成的迁移创建列如下(例子)之后

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

你的意思是这样的:def self.up add_column ... end add_index ...? – user1611830 2013-04-08 14:34:00

45

如果你需要创建一个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两者柱后和索引将被添加到product表。

如果您只是需要向现有列添加索引,例如一个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 
+0

感谢Vadym的完整答案。最后一个问题:为什么你会建议撤消初始迁移?以后有没有关于添加索引的性能问题? – 2015-05-24 16:44:56

+2

对@fwuensche:稍后添加索引不会有性能损失。但是,域逻辑不太清晰。例如。如果你决定稍后打破/抽象/关联该关联,则需要处理两个单独的迁移,这本应该是单个迁移... – 2015-06-01 19:01:07

+2

警告:请注意,索引:true仅适用于create_table迁移。迁移将运行,但不会创建索引。请参阅https://makandracards.com/makandra/32353-psa-index-true-in-rails-migrations-does-not-work-as-you-d-expect – rmcsharry 2016-08-20 22:25:31

1

对于引用你可以这样调用

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 :dt_json_structs, :ordination_number, unique: true 
    end 
end