Pergunta

Experiente com Rails/ActiveRecord 2.1.1

  • Você cria uma primeira versão com (por exemplo) Ruby script\generate scaffold product title:string description:text image_url:string
  • Isso cria (por exemplo) um arquivo de migração chamado 20080910122415_create_products.rb
  • Você aplica a migração com rake db:migrate
  • Agora, você adiciona um campo à tabela de produtos com script Ruby\generate migração add_price_to_product price:decimal
  • Isso cria um arquivo de migração chamado 20080910125745_add_price_to_product.rb
  • Se você tentar executar rake db:migrate, ele irá na verdade reverter a primeira migração, e não aplicar a próxima!Portanto, sua tabela de produtos será destruída!
  • Mas se você executasse o rake sozinho, isso lhe diria que uma migração estava pendente

Por favor, observe que a aplicação de rake db:migrate (depois que a tabela for destruída) aplicará todas as migrações em ordem.

A única solução que encontrei foi especificar a versão da nova migração como em:

rake db:migrate version=20080910125745

Então estou me perguntando:este é um novo comportamento esperado?

Foi útil?

Solução

Você deve ser capaz de usar

rake db:migrate:up 

para forçá-lo a avançar, mas você corre o risco de perder migrações intercaladas de outras pessoas da sua equipe

se você correr

rake db:migrate 

duas vezes, ele reaplicará todas as suas migrações.

Encontro o mesmo comportamento em janelas com SQLite, pode ser um bug específico para tal ambiente.

Editar - Eu descobri o porquê.Na tarefa railstie database.rake você tem o seguinte 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

Então nas minhas variáveis ​​de ambiente eu tenho

echo %Version% #=> V3.5.0f

em rubi

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

assim a tarefa rake chama

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

e em ActiveRecord::Migrator temos:

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

Sim, rake db:migrate VERSION=0 é a versão longa para rake db:migrate:down

Editar - Eu iria atualizar o bug do farol, mas o proxy da superempresa proíbe que eu me conecte lá

Enquanto isso, você pode tentar desativar a versão antes de chamar a migração ...

Outras dicas

Discordo respeitosamente, Tom!esse é um inseto !!V3.5.0f não é uma versão válida para migrações rake.Rake não deve usá-lo para migrar:down só porque Ruby escolheu considerar que "V3.5.0f".to_i é 0 ...

Rake deve reclamar em voz alta que a versão não é válida para que os usuários saibam o que está acontecendo (entre você e eu, verificando se a versão é um registro de data e hora formado por yyyyymmdd, convertendo para inteiro, é um pouco leve)

[Maldito IE6, isso não me permite comentar!e não, não posso mudar de navegador, obrigado corporativo]

Este não é o comportamento esperado.Eu ia sugerir relatar isso como um bug no farol, mas vejo que você já fiz isso!Se você fornecer mais informações (incluindo versão do sistema operacional/banco de dados/ruby), darei uma olhada.

João,

Muito obrigado pela sua investigação.Você está certo e, na verdade, acho que descobriu um bug mais grave, da espécie 'bug de design'.

O que está acontecendo é que rake pegará qualquer valor que você passar para a linha de comando e os armazenará como variáveis ​​de ambiente.As tarefas rake que eventualmente serão chamadas apenas extrairão esses valores da variável de ambiente.Quando db:migrate consulta ENV["VERSION"], ele na verdade solicita o parâmetro de versão que você definiu chamando rake.Ao chamar rake db:migrate, você não passa nenhuma versão.

Mas temos uma variável de ambiente chamada VERSION que foi definida para outros fins por algum outro programa (ainda não sei qual).E os caras por trás do rake (ou por trás do database.rake) não imaginaram que isso iria acontecer.Isso é um bug de design.Pelo menos, eles poderiam ter usado nomes de variáveis ​​mais específicos como "RAKE_VERSION" ou "RAKE_PARAM_VERSION" em vez de apenas "VERSION".

Tom, definitivamente não irei fechar, mas editarei meu relatório de bug no farol para refletir essas novas descobertas.

E obrigado novamente Jean pela sua ajuda.Postei esse bug no farol há cerca de 5 dias e ainda não obtive resposta!

Rolo

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top