En général, il devrait être possible de mettre à jour les anciens documents avec les nouveaux champs lors de l'exécution. Il n'y a pas besoin de migrations dans MongoDB.
Vous voudrez peut-être écrire des tâches de ratissage pour mettre à jour vos anciens documents avec les nouveaux champs et les valeurs par défaut.
Vous pourriez trouver ces documents en vérifiant ces nouveaux champs qui ont par défaut une valeur nulle.
Mettre à jour
Style simple :
Si vous définissez un nouveau champ avec une valeur par défaut, cette valeur doit toujours être utilisée tant que vous en définissez une nouvelle :
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
Si vous interrogez votre base de données, vous devriez obtenir votre valeur par défaut pour les documents qui n'ont pas ce champ avant votre extension :
(console de rails)
MyModel.first
#=> #<MyModel …other fields…, note: "no note given so far!">
J'ai testé cela avec une nouvelle pile de rails avec un mongoid actuel sur Ruby 1.9.2 - devrait également fonctionner avec d'autres piles.
Style plus compliqué/complexe :
Si vous n'avez pas défini de valeur par défaut, vous obtiendrez nil pour ce nouveau champ.
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 rails)
MyModel.first
#=> #<MyModel …other fields…, note: nil>
Ensuite, vous pouvez configurer une tâche de rake et un fichier de migration comme dans cet exemple :
lib/tasks/my_model_migration.rake :
namespace :mymodel do
desc "MyModel migration task"
task :migrate => :environment do
require "./db/migrate.rb"
end
end
db/migrate.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
Exécutez cette migration avec rake mymodel:migrate
.
Ce n'est qu'un point de départ et vous pouvez l'étendre à un moteur de migration mongoid complet.
La task :migrate => :environment do …
est nécessaire, sinon rake ne chargera pas les modèles.