Ok consegui passar. Acho que existe uma maneira mais rápida de usar o console do mongo com algo assim:MongoDB:Como alterar o tipo de um campo?
Mas não consegui fazer a conversão funcionar, então optei por esse método mais lento no console do rails com mais tempo de inatividade. Se alguém tiver uma solução mais rápida por favor poste.
- crie um novo campo Integer com um novo nome, digamos
amount2
- converter cada
amount
para o valor correto paraamount2
em um console ou tarefa de rake
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.amount2 = t.amount.to_money
break if !t.save
end
Observe que .all.each funciona bem (você não precisa usar .find_each ou .find_in_batches como activerecord regular com mysql) por causa dos cursores mongodb. Ele não encherá a memória enquanto o identity_map estiver desativado.
-
desative o site para manutenção, execute a migração mais uma vez para capturar quaisquer campos de quantidade que possam ter sido alterados nos últimos minutos (algo comoTransaction.where(:updated_at.gt => 1.hour.ago).each_with_index...
-
comentefield :amount, type: BigDecimal
no seu modelo, você não quer que o mongoid saiba mais sobre esse campo e envie este código
- agora execute outro script para renomear sua coluna (ele substitui qualquer valor de string BigDecimal antigo no processo). Talvez seja necessário comentar quaisquer validações que você tenha no modelo que espera o campo antigo.
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.rename :amount2, :amount
end
Isso é atômico e não requer salvar o modelo.
- atualize seu modelo para refletir o novo tipo de coluna
field :amount, type: Integer
- implante e reative o site
Como mencionado, acho que há uma maneira melhor, então se alguém tiver algumas dicas, por favor, compartilhe. Obrigado!