Pregunta

Experimentado con Rails / ActiveRecord 2.1.1

  • Crea una primera versión con (por ejemplo) ruby ​​script\generate scaffold título del producto:cadena descripción:texto image_url:cadena
  • Esto crea (por ejemplo) un archivo de migración llamado 20080910122415_create_products.rb
  • Aplicas la migración con rake db:migrate
  • Ahora, agrega un campo a la tabla de productos con Ruby script\generar migración add_price_to_product precio:decimal
  • Esto crea un archivo de migración llamado 20080910125745_add_price_to_product.rb
  • Si intenta ejecutar rake db:migrate, en realidad revertirá la primera migración, ¡no aplicará la siguiente!¡Así que tu tabla de productos quedará destruida!
  • Pero si ejecutara rake solo, le habría dicho que había una migración pendiente.

Tenga en cuenta que al aplicar rake db:migrate (una vez que se haya destruido la tabla) se aplicarán todas las migraciones en orden.

La única solución que encontré es especificar la versión de la nueva migración como en:

rake db:migrate version=20080910125745

Entonces me pregunto:¿Es este un nuevo comportamiento esperado?

¿Fue útil?

Solución

Deberías poder utilizar

rake db:migrate:up 

para forzarlo a seguir adelante, pero luego corre el riesgo de perderse migraciones intercaladas de otras personas de su equipo

si tu corres

rake db:migrate 

dos veces, volverá a aplicar todas sus migraciones.

Encuentro el mismo comportamiento en Windows con SQLite, podría ser un error específico de dicho entorno.

Editar --Encontré por qué.En la tarea Railstie Database.rake tienes el siguiente código:

desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
task :migrate => :environment do
  ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
  ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
  Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
end

Luego en mis variables de entorno tengo

echo %Version% #=> V3.5.0f

en rubí

ENV["VERSION"] # => V3.5.0f
ENV["VERSION"].to_i #=>0 not nil !

por lo tanto, la tarea de rastrillo llama

ActiveRecord::Migrator.migrate("db/migrate/", 0)

y en ActiveRecord::Migrator tenemos:

class Migrator#:nodoc:
  class << self
    def migrate(migrations_path, target_version = nil)
      case
        when target_version.nil?              then up(migrations_path, target_version)
        when current_version > target_version then down(migrations_path, target_version)
        else                                       up(migrations_path, target_version)
      end
    end

Sí, rake db:migrate VERSION=0 es la versión larga para rake db:migrate:down

Editar - Iría a actualizar el error del faro, pero el proxy de la súper empresa me prohíbe conectarme allí.

Mientras tanto, puede intentar desarmar la versión antes de llamar a migrar...

Otros consejos

¡Respetuosamente no estoy de acuerdo, Tom!este es un insecto !!V3.5.0f no es una versión válida para migraciones de rake.Rake no debería usarlo para migrar: abajo solo porque Ruby decidió considerar que "V3.5.0f".to_i es 0...

Rake debe quejarse en voz alta de que la versión no es válida para que los usuarios sepan lo que está pasando (entre usted y yo, verificar que la versión es una marca de tiempo formada yyyymmdd al convertir en entero es un poco ligero)

[¡Maldito IE6 que no me permite comentar!y no, no puedo cambiar de navegador gracias corporativo]

Este no es el comportamiento esperado.Iba a sugerir informar esto como un error en Lighthouse, pero veo que ya ya lo hice!Si proporciona más información (incluido el sistema operativo/base de datos/versión Ruby), la echaré un vistazo.

Vaquero,

Muchas gracias por tu investigación.Tienes razón y, de hecho, creo que has descubierto un error más grave, del tipo "error de diseño".

Lo que sucede es que rake tomará cualquier valor que pase a la línea de comando y lo almacenará como variables de entorno.Las tareas de rake que eventualmente serán llamadas simplemente extraerán estos valores de la variable de entorno.Cuando db:migrate consulta ENV["VERSION"], en realidad solicita el parámetro de versión que configuró llamando a rake.Cuando llamas a rake db:migrate, no pasas ninguna versión.

Pero tenemos una variable de entorno llamada VERSIÓN que algún otro programa ha configurado para otros propósitos (aún no sé cuál).Y los chicos detrás de rake (o detrás de la base de datos.rake) no se imaginaron que esto sucedería.Eso es un error de diseño.Al menos, podrían haber usado nombres de variables más específicos como "RAKE_VERSION" o "RAKE_PARAM_VERSION" en lugar de solo "VERSION".

Tom, definitivamente no cerraré, pero editaré mi informe de error en Lighthouse para reflejar estos nuevos hallazgos.

Y gracias de nuevo Jean por tu ayuda.¡Publiqué este error en Lighthouse hace como 5 días y todavía no obtuve respuesta!

rollo

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top