Robiłem takie rzeczy podczas moich migracji:
add_column :statuses, :hold_reason, :string rescue puts "column already added"
ale okazuje się, że chociaż działa to dla SQLite, nie działa dla PostgreSQL . Wydaje się, że jeśli add_column wybuchnie, nawet jeśli wyjątek zostanie przechwycony, transakcja jest martwa i migracja nie może wykonać żadnej dodatkowej pracy.
Czy są jakieś specyficzne sposoby sprawdzenia, czy kolumna lub tabela już istnieje? Jeśli to się nie uda, czy jest jakiś sposób, aby mój blok ratunkowy naprawdę działał?
ruby-on-rails
migration
Dan Rosenstark
źródło
źródło
Odpowiedzi:
Począwszy od Rails 3.0 i późniejszych, możesz użyć
column_exists?
do sprawdzenia istnienia kolumny.unless column_exists? :statuses, :hold_reason add_column :statuses, :hold_reason, :string end
Jest też
table_exists?
funkcja, która sięga wstecz do Railsów 2.1.źródło
Albo jeszcze krócej
add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason
źródło
W przypadku Rails 2.X możesz sprawdzić istnienie kolumn, wykonując następujące czynności:
columns("[table-name]").index {|col| col.name == "[column-name]"}
Jeśli zwraca nil, taka kolumna nie istnieje. Jeśli zwraca Fixnum, kolumna istnieje. Oczywiście możesz umieścić bardziej selektywne parametry między
{...}
kolumnami, jeśli chcesz identyfikować kolumnę nie tylko na podstawie jej nazwy, na przykład:{ |col| col.name == "foo" and col.sql_type == "tinyint(1)" and col.primary == nil }
(ta odpowiedź została po raz pierwszy opublikowana na Jak pisać migracje warunkowe w railsach? )
źródło
add_column :statuses, :hold_reason, :string unless Status.column_names.include?("hold_reason")
źródło