2013-04-08 117 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