2009-09-19 17 views

risposta

551

La risposta breve:

add_index :table_name, :column_name, unique: true 

per indicizzare più colonne insieme, si passa una serie di nomi di colonne invece di un nome della singola colonna,

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

Per grana più fine controllo, c'è un " execute "metodo che esegue direttamente SQL.

Questo è tutto!

Se si esegue questa operazione in sostituzione delle normali convalide del modello precedente, è sufficiente controllare per vedere come funziona. Non sono sicuro che l'errore di segnalazione all'utente sarà altrettanto bello. Puoi sempre fare entrambe le cose.

+33

+1 per suggerire di continuare a utilizzare validates_uniqueness_of. La gestione degli errori è molto più pulita utilizzando questo metodo per il costo di una singola query indicizzata. Suggerirei di fare entrambe le cose –

+1

Ho provato che non sembra funzionare! Potrei inserire due record con column_name che ho definito unico! Sto usando Rails 2.3.4 e MySql qualche idea? – Tam

+0

Ho usato il secondo suggerimento usando execute: esegui "ALTER TABLE users ADD UNIQUE (email)" e funziona! Non sono sicuro del motivo per cui il primo non sarebbe stato interessato a conoscere – Tam

97

rails generate migrazione add_index_to_table_name colonna column: uniq

o

apparati generano migrazione add_column_name_to_table_name colonna column: stringa: uniq: indice

genera

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

Se si aggiunge un indice per una colonna esistente, rimuovere o commentare la linea add_column, o mettere in un assegno

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

Ho svitato questo perché volevo il modulo della riga di comando. Ma è sciocco che aggiunge la colonna anche quando specifichi 'add_index ...' e non 'add_column ...'. –

+1

Yeap, forse nella prossima versione. –

7

sto usando Rails 5 e le risposte di cui sopra grande lavoro; ecco un altro modo in cui ha lavorato anche per me (il nome della tabella è :people e il nome della colonna è :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

si potrebbe desiderare di aggiungere il nome per la chiave univoca, come molte volte il default unique_key nome con rotaie può essere troppo lungo per il quale il DB può lanciare l'errore.

Per aggiungere un nome all'indice, utilizzare l'opzione name:. La query di migrazione potrebbe essere qualcosa di simile -

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

Maggiori informazioni - http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

17

Dal momento che questo non è stato ancora citato, ma risponde alla domanda che ho avuto quando ho trovato questa pagina, è possibile anche specificare che un indice dovrebbe essere unico quando si aggiunge tramite t.references o t.belongs_to:

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

    # other columns... 
end 

(come di almeno Rails 4.2.7)

1
add_index :table_name, :column_name, unique: true 

Per indicizzare più colonne insieme, si passa una matrice di nomi di colonne invece di un nome di singola colonna.

Problemi correlati