2013-04-08 35 views
65

Giả sử tôi đã tạo một bảng table trong ứng dụng Rails. Một thời gian sau, tôi thêm cột chạy:Đường ray: Thêm chỉ mục sau khi thêm cột

rails generate migration AddUser_idColumnToTable user_id:string. 

Sau đó, tôi nhận thấy rằng tôi cần thêm user_id làm chỉ mục. Tôi biết về phương pháp add_index, nhưng phương pháp này nên được gọi ở đâu? Tôi có nên chạy một di cư (nếu có, cái nào?), Sau đó thêm bằng tay phương pháp này?

Trả lời

147

Bạn có thể chạy di cư khác, chỉ dành riêng cho các chỉ số:

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

Vì vậy, tôi chỉ cần chạy trong giao diện điều khiển của tôi: đường ray tạo ra di chuyển AddIndexToTable? – user1611830

+1

Có, bạn có thể làm điều đó, nhưng bạn sẽ phải chỉnh sửa di chuyển đó sau đó để phản ánh mã trên. –

+0

vâng, cảm ơn! – user1611830

7

Thêm vào sự di cư được tạo ra sau khi tạo cột như sau (ví dụ)

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

bạn có nghĩa là một cái gì đó như thế này: def self.up add_column ... end add_index ...? – user1611830

45

Nếu bạn cần để tạo ra một user_id sau đó nó sẽ là một giả định hợp lý mà bạn đang tham khảo một bảng người dùng. Trong trường hợp này, sự di cư phải:

rails generate migration AddUserRefToProducts user:references 

Lệnh này sẽ tạo ra sự di cư sau:

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

Sau khi chạy rake db:migrate cả một cột và một chỉ số sẽ được thêm vào product bảng.

Trong trường hợp bạn chỉ cần thêm chỉ mục vào cột hiện tại, ví dụ: name của một bảng user, kỹ thuật sau đây có thể hữu ích:

rails generate migration AddIndexToUsers name:string:index sẽ tạo ra sự di cư sau:

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

Xóa add_column dòng và chạy di cư.

Trong trường hợp được mô tả, bạn có thể đã đưa ra lệnh rails generate migration AddIndexIdToTable index_id:integer:index và sau đó xóa add_column dòng khỏi di chuyển được tạo. Nhưng tôi thà khuyến khích để hoàn tác di chuyển ban đầu và thêm tài liệu tham khảo thay vì:

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

Cảm ơn Vadym vì câu trả lời hoàn chỉnh. Một câu hỏi cuối cùng: tại sao bạn khuyên bạn nên hoàn tác việc di chuyển ban đầu? Có vấn đề về hiệu suất nào liên quan đến việc thêm chỉ mục sau này không? –

+2

Để @fwuensche: không có hình phạt về hiệu suất để thêm chỉ mục sau này. Tuy nhiên, logic miền sẽ ít rõ ràng hơn. Ví dụ. trong trường hợp bạn quyết định phá vỡ/abstract/etc liên kết sau này, bạn cần phải xử lý hai lần di chuyển riêng biệt, mà thực sự cần phải là một lần duy nhất ... –

+2

CẢNH BÁO: Lưu ý rằng chỉ mục: true chỉ hoạt động trong một create_table migration. Việc di chuyển sẽ chạy, nhưng không có chỉ mục nào được tạo. Xem https://makandracards.com/makandra/32353-psa-index-true-in-rails-migrations-does-not-work-as-you-d-expect – rmcsharry

1

Đối với tài liệu tham khảo bạn có thể gọi

rails generate migration AddUserIdColumnToTable user:references 

Nếu trong tương lai bạn cần phải thêm một chỉ số chung, bạn có thể khởi chạy này

rails g migration AddOrdinationNumberToTable ordination_number:integer:index 

Tạo mã:

class AddOrdinationNumberToTable < ActiveRecord::Migration 
    def change 
    add_column :tables, :ordination_number, :integer 
    add_index :dt_json_structs, :ordination_number, unique: true 
    end 
end 
Các vấn đề liên quan