2009-10-29 17 views
53

que estaba haciendo este tipo de cosas en mis migraciones:Migraciones de rieles: verificar la existencia y seguir avanzando?

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

pero resulta que, mientras esto funciona para SQLite, que no funciona para PostgreSQL. Parece que si add_column explota, , incluso si se detecta la excepción, la transacción está muerta y la migración no puede hacer ningún trabajo adicional.

¿Hay alguna forma no específica de BD para comprobar si ya existe una columna o una tabla? En su defecto, ¿hay alguna forma de que mi bloque de rescate funcione realmente?

Respuesta

132

A partir de Rails 3.0 y posterior, puede usar column_exists? para verificar la existencia de una columna.

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

También hay una función table_exists?, que va tan lejos como Rails 2.1.

+0

¿es considerado el mejor pract ice para verificar si existe una columna/tabla antes de agregar/crearla? (Sé que por supuesto depende del problema en las manos) –

+2

¿Funciona esto con retrocesos si lo defino en el método de cambio? – dardub

+0

Sí, la reversión sería un problema ... no estamos seguros de si deberíamos eliminar la columna o no ... ya que no estamos grabando el estado anterior. – songyy

4

Para rieles 2.X, se puede comprobar la existencia de columnas con lo siguiente:

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

Si devuelve nil, no existe tal columna. Si devuelve un Fixnum, entonces la columna existe. Naturalmente, se puede poner parámetros más selectivas entre el {...} si desea identificar una columna por algo más que su nombre, por ejemplo:

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

(esta respuesta primero publicado en How to write conditional migrations in rails?)

0

add_column: estados ,: hold_reason,?: cadena a menos Status.column_names.include ("hold_reason")

5

O incluso más corto

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

esto sería un comentario en la otra respuesta, no una respuesta. Gracias. –

Cuestiones relacionadas