web-dev-qa-db-fra.com

Rails Migrations: vérifier l'existence et continuer?

Je faisais ce genre de chose dans mes migrations:

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

mais il s'avère que, alors que cela fonctionne pour SQLite, cela ne fonctionne pas pour PostgreSQL. Il semble que si add_column explose, même si l'exception est interceptée la transaction est morte et donc la migration ne peut pas faire de travail supplémentaire.

Existe-t-il des moyens non spécifiques à la base de données pour vérifier si une colonne ou une table existe déjà? À défaut, y a-t-il un moyen de faire fonctionner mon bloc de sauvetage?

69
Dan Rosenstark

À partir de Rails 3.0 et versions ultérieures, vous pouvez utiliser column_exists? pour vérifier l'existence d'une colonne.

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

Il y a aussi un table_exists? , qui remonte à Rails 2.1.

156
Tobias Cohen

Ou encore plus court

add_column :statuses, :hold_reason, :string unless column_exists? :statuses, :hold_reason
7
SG 86

Pour Rails 2.X , vous pouvez vérifier l'existence de colonnes avec les éléments suivants:

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

S'il renvoie nil, aucune colonne de ce type n'existe. S'il renvoie un Fixnum, la colonne existe. Naturellement, vous pouvez mettre des paramètres plus sélectifs entre les {...} si vous souhaitez identifier une colonne par plus que son nom, par exemple:

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

(cette réponse a d'abord été publiée le Comment écrire des migrations conditionnelles dans des rails? )

4
JellicleCat

add_column :statuses, :hold_reason, :string unless Status.column_names.include?("hold_reason")

0
Denis Neverov