Като цяло трябва да е възможно да се актуализират стари документи с новите полета по време на изпълнение. Няма нужда от миграции в MongoDB.
Може би искате да напишете рейк задачи, за да актуализирате старите си документи с новите полета и стойности по подразбиране.
Можете да откриете тези документи, като проверите тези нови полета, които по подразбиране имат нулева стойност.
Актуализация
Лесен стил:
Ако дефинирате ново поле със стойност по подразбиране, тази стойност винаги трябва да се използва, докато зададете нова:
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
Ако направите запитване към вашата база данни, трябва да получите стойността си по подразбиране за документи, които нямат това поле преди вашето разширение:
(конзола за релси)
MyModel.first
#=> #<MyModel …other fields…, note: "no note given so far!">
Тествах това с нов стек на rails с текущ монгоид на Ruby 1.9.2 - трябва да работи и с други стекове.
По-сложен/сложен стил:
Ако не сте задали стойност по подразбиране, ще получите нула за това ново поле.
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
(конзола за релси)
MyModel.first
#=> #<MyModel …other fields…, note: nil>
След това можете да настроите рейк задача и файл за миграция, както в този пример:
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
Изпълнете тази миграция с rake mymodel:migrate
.
Това е само начална точка и можете да я разширите до пълна машина за миграция на mongoid.
task :migrate => :environment do …
е необходимо, в противен случай рейкът няма да зареди модели.