2009-10-29 9 views
53

stavo facendo questo genere di cose nelle mie migrazioni:Migrazioni delle rotaie: verifica l'esistenza e continua a procedere?

add_column :statuses, :hold_reason, :string rescue puts "column already added" 

Ma si scopre che, mentre questo funziona per SQLite, non funziona per PostgreSQL. Sembra che se la colonna add_column esplode, anche se viene rilevata l'eccezione, la transazione è morta e quindi la migrazione non può eseguire alcun lavoro aggiuntivo.

Esistono non DB modi per verificare se una colonna o tabella esistono già? In caso contrario, c'è un modo per far funzionare davvero il mio blocco di soccorso?

risposta

132

A partire da Rails 3.0 e versioni successive, è possibile utilizzare column_exists? per verificare l'esistenza di una colonna.

unless column_exists? :statuses, :hold_reason 
    add_column :statuses, :hold_reason, :string 
end 

C'è anche una funzione di table_exists?, che va nel lontano Rails 2.1.

+0

E 'considerato il miglior pract ghiaccio per controllare se esiste una colonna/tabella prima di aggiungerla/crearla? (So ​​che ovviamente dipende dal problema nelle mani) –

+2

Questo funziona con i rollback se lo definisco nel metodo di modifica? – dardub

+0

Sì, il rollback sarebbe un problema ... non siamo sicuri se rimuovere la colonna o meno ... dal momento che non stiamo registrando lo stato precedente. – songyy

4

Per Rails 2.X, è possibile verificare l'esistenza di colonne con il seguente:

columns("[table-name]").index {|col| col.name == "[column-name]"} 

Se restituisce nil, non esiste una tale colonna. Se restituisce un Fixnum, la colonna esiste. Naturalmente, si può mettere i parametri più selettivi tra l'{...} se si vuole identificare una colonna di oltre solo il suo nome, per esempio:

{ |col| col.name == "foo" and col.sql_type == "tinyint(1)" and col.primary == nil } 

(questa risposta prima pubblicato su How to write conditional migrations in rails?)

0

add_column: status ,: hold_reason,:? stringa a meno che Status.column_names.include ("hold_reason")

5

O anche più breve

add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason 
+0

questo sarebbe un commento sull'altra risposta, non una risposta. Grazie. –

Problemi correlati