2013-04-08 15 views
65

Załóżmy, że utworzyłem tabelę table w aplikacji Rails. Jakiś czas później, dodać bieg kolumna:Szyny: Dodawanie indeksu po dodaniu kolumny

rails generate migration AddUser_idColumnToTable user_id:string. 

Potem sobie sprawę, że trzeba dodać user_id jako wskaźnik. Wiem o metodzie add_index, ale gdzie powinna się nazywać ta metoda? Czy mam przeprowadzić migrację (jeśli tak, która?), A następnie ręcznie dodać tę metodę?

Odpowiedz

147

można uruchomić kolejną migrację, tylko dla wskaźnika:

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

Po prostu uruchamiam w mojej konsoli: szyny generują migrację AddIndexToTable? – user1611830

+1

Tak, możesz to zrobić, ale potem będziesz musiał edytować tę migrację, aby odzwierciedlić powyższy kod. –

+0

tak, dziękuję! – user1611830

7

Dodaj w wygenerowanym migracji po utworzeniu kolumny następująco (przykład)

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

masz na myśli coś takiego: def self.up add_column ... end add_index ...? – user1611830

45

Jeśli trzeba utworzyć user_id wtedy byłoby rozsądnym założeniem, że odwołujesz się do tabeli użytkowników. W tym przypadku migracji następuje:

rails generate migration AddUserRefToProducts user:references 

Polecenie generować następujące migracji:

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

Po uruchomieniu rake db:migrate zarówno kolumnę i indeks zostanie dodany do product tabeli.

W przypadku, gdy wystarczy dodać indeks do istniejącej kolumny, np. name z user tabeli następujące technika może być pomocne:

rails generate migration AddIndexToUsers name:string:index wygeneruje następujący migracji:

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

Usuń add_column linii i uruchom migrację.

W opisanym przypadku można było wydać polecenie rails generate migration AddIndexIdToTable index_id:integer:index, a następnie usunąć linię add_column z wygenerowanej migracji. Ale wolałbym zaleca się cofnąć wstępnej migracji i dodać odniesienie zamiast:

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

Dzięki Vadym za kompletną odpowiedź. Ostatnie pytanie: dlaczego poleciłbyś cofnąć początkową migrację? Czy jest jakiś problem z wydajnością związany z dodawaniem indeksu w późniejszym czasie? –

+2

To @fwuensche: nie ma kary za wydajność późniejszego dodawania indeksu. Logika domeny będzie jednak mniej jasna. Na przykład. w przypadku, gdy zdecydujesz się na złamanie/streszczenie/etc skojarzenie później, musisz mieć do czynienia z dwiema oddzielnymi migracjami, które tak naprawdę powinny być jednym ... –

+2

OSTRZEŻENIE: Zwróć uwagę, że indeks: true działa tylko w Migracja create_table. Migracja zostanie uruchomiona, ale nie zostanie utworzony żaden indeks. Zobacz https://makandracards.com/makandra/32353-psa-index-true-in-rails-migrations-does-not-work-as-you-d-expect – rmcsharry

1

Dla odniesień można nazwać

rails generate migration AddUserIdColumnToTable user:references 

Jeśli w przyszłości trzeba dodać ogólny indeks ten można uruchomić

rails g migration AddOrdinationNumberToTable ordination_number:integer:index 

wygenerować kod:

class AddOrdinationNumberToTable < ActiveRecord::Migration 
    def change 
    add_column :tables, :ordination_number, :integer 
    add_index :dt_json_structs, :ordination_number, unique: true 
    end 
end 
Powiązane problemy