В общем случае должна быть возможность обновить старые документы новыми полями во время выполнения. В MongoDB нет необходимости в миграции.
Возможно, вы захотите написать грабли для обновления старых документов новыми полями и значениями по умолчанию.
Вы можете узнать эти документы, проверив те новые поля, которые по умолчанию имеют значение nil.
Обновление
Простой стиль:
Если вы определяете новое поле со значением по умолчанию, это значение всегда должно использоваться, пока вы устанавливаете новое:
приложение / модели / 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!">
Я протестировал это со свежим стеком рельсов с текущим монгоидом на Ruby 1.9.2 - должно работать и с другими стеками.
Более сложный / сложный стиль:
Если вы не установили значение по умолчанию, вы получите ноль для этого нового поля.
приложение / модели / 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>
Затем вы можете настроить задачу rake и файл миграции, как в этом примере:
Библиотека / Задачи / my_model_migration.rake:
namespace :mymodel do
desc "MyModel migration task"
task :migrate => :environment do
require "./db/migrate.rb"
end
end
дб / 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 …
, иначе грабли не будут загружать модели.