2009-09-19 10 views

Odpowiedz

551

Krótka odpowiedź:

add_index :table_name, :column_name, unique: true 

do indeksu wielu kolumn razem, mijamy tablicę z nazwami kolumn zamiast pojedynczej nazwy kolumny,

add_index :table_name, [:column_name_a, :column_name_b], unique: true 

Do drobniejszych szczegółową kontrolę, nie ma " execute "metoda, która wykonuje prosty SQL.

To wszystko!

Jeśli robisz to jako zamiennik dla standardowych sprawdzania starego modelu, po prostu sprawdź, jak działa. Nie jestem pewien, czy zgłoszenie błędu do użytkownika będzie równie miłe. Zawsze możesz zrobić jedno i drugie.

+33

+1 za sugerowanie dalszego używania validates_uniqueness_of. Obsługa błędów jest znacznie czystsza przy użyciu tej metody dla kosztu pojedynczej indeksowanej kwerendy, którą sugerowałbym, aby zrobił zarówno –

+1

Próbowałem, że to nie działa! Mógłbym wstawić dwa rekordy z column_name, które zdefiniowałem jako unikatowe! Używam Rails 2.3.4 i MySql jakieś pomysły? – Tam

+0

Użyłem twojej drugiej sugestii używając execute: wykonaj "ALTER TABLE users ADD UNIQUE (email)" i to działa! nie jestem pewien, dlaczego ten pierwszy nie byłby zainteresowany poznaniem – Tam

97

szyny generowania migracji add_index_to_table_name nazwa_kolumny: uniq

lub

szyny generowania migracji add_column_name_to_table_name nazwa_kolumny STRING: uniq: wskaźnik

generuje

class AddIndexToModerators < ActiveRecord::Migration 
    def change 
    add_column :moderators, :username, :string 
    add_index :moderators, :username, unique: true 
    end 
end 

Jeśli dodanie indeksu do istniejącej kolumny, usuwać lub komentarz linię add_column, lub umieścić w czeku

add_column :moderators, :username, :string unless column_exists? :moderators, :username 
+4

Przegłosowałem to, ponieważ chciałem formularza wiersza polecenia. Ale jest głupio, że dodaje kolumnę, nawet gdy podaję 'add_index ...', a nie 'add_column ...'. –

+1

Yeap, może w następnej wersji. –

7

używam szyn 5 i powyższe odpowiedzi działają świetnie; Oto kolejny sposób, który również pracował dla mnie (nazwa tabeli jest :people i nazwa kolumny jest :email_address)

class AddIndexToEmailAddress < ActiveRecord::Migration[5.0] 
    def change 
    change_table :people do |t| 
     t.index :email_address, unique: true 
    end 
    end 
end 
0

Możesz też dodać nazwę dla unikalnego klucza tyle razy domyślnego unique_key nazwy wg szyn może być zbyt długo, dla których DB może rzucić błąd.

Aby dodać nazwę indeksu, wystarczy użyć opcji name:. Zapytanie migracja może wyglądać mniej więcej tak -

add_index :table_name, [:column_name_a, :column_name_b, ... :column_name_n], unique: true, name: 'my_custom_index_name'

Więcej info - http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

17

Ponieważ nie zostały jeszcze wymienione, ale odpowiedź na pytanie miałem kiedy znalazłem tę stronę, można również określić, że indeks powinien być unikalny podczas dodawania go poprzez t.references lub t.belongs_to:

create_table :accounts do |t| 
    t.references :user, index: { unique: true } # or t.belongs_to 

    # other columns... 
end 

(od co najmniej Rails 4.2.7)

1
add_index :table_name, :column_name, unique: true 

Aby indeksować wiele kolumn jednocześnie, należy podać tablicę nazw kolumn zamiast pojedynczej nazwy kolumny.