Em geral, deve ser possível atualizar documentos antigos com os novos campos em tempo de execução. Não há necessidade de migrações no MongoDB.
Talvez você queira escrever tarefas de rake para atualizar seus documentos antigos com os novos campos e valores padrão.
Você pode descobrir esses documentos verificando os novos campos que têm por padrão um valor nulo.
Atualizar
Estilo fácil:
Se você definir um novo campo com um valor padrão, esse valor sempre deve ser usado desde que você defina um novo:
app/models/my_model.rb
class MyModel
include Mongoid::Document
field :name, type: String
field :data, type: String
# NEW FIELD
field :note, type: String, default: "no note given so far!"
end
Se você consultar seu banco de dados, deverá obter seu valor padrão para documentos que não tenham este campo antes de sua extensão:
(console de trilhos)
MyModel.first
#=> #<MyModel …other fields…, note: "no note given so far!">
Eu testei isso com uma nova pilha de trilhos com um mongoid atual no Ruby 1.9.2 - deve funcionar com outras pilhas também.
Estilo mais complicado/complexo:
Se você não definiu um valor padrão, receberá nil para este novo campo.
app/models/my_model.rb
class MyModel
include Mongoid::Document
field :name, type: String
field :data, type: String
# NEW FIELD
field :note, type: String
end
(console de trilhos)
MyModel.first
#=> #<MyModel …other fields…, note: nil>
Então você pode configurar uma tarefa de rake e um arquivo de migração como neste exemplo:
lib/tasks/my_model_migration.rake:
namespace :mymodel do
desc "MyModel migration task"
task :migrate => :environment do
require "./db/migrate.rb"
end
end
db/migrar.rb:
olds = MyModel.where(note: nil)
# Enumerator of documents without a valid :note field (= nil)
olds.each do |doc|
doc.note = "(migration) no note given yet"
# or whatever your desired default value should be
doc.save! rescue puts "Could not modify doc #{doc.id}/#{doc.name}"
# the rescue is only a failsafe statement if something goes wrong
end
Execute esta migração com
rake mymodel:migrate
. Este é apenas um ponto de partida e você pode estender isso para um mecanismo de migração mongoid completo.
A
task :migrate => :environment do …
é necessário, caso contrário, o rake não carregará os modelos.