Если вы хотите выполнить всю миграцию одновременно, то mongoid_rails_migrations сделает то, что вам нужно.На самом деле не так много документов, они дублируют функциональность стандартной миграции ActiveRecord.Вы пишете свои миграции, а затем используете rake db:migrate
, чтобы применить их, и это помогает определить, какие из них были, а какие не были выполнены.Я могу ответить на дополнительные вопросы, если есть что-то конкретное, что вы хотите знать об этом.
Для отложенных миграций самое простое решение - использовать обратный вызов after_initialize .Проверьте, соответствует ли поле старой схеме данных и изменяет ли она объект и обновляет ли его, например:
class Person
include Mongoid::Document
after_initialize :migrate_data
field :name, :type => String
def migrate_data
if !self[:first_name].blank? or !self[:last_name].blank?
self.set(:name, "#{self[:first_name]} #{self[:last_name]}".strip)
self.remove_attribute(:first_name)
self.remove_attribute(:last_name)
end
end
end
Компромиссы, о которых следует помнить, с конкретным подходом, который я дал выше:
Если вы запустите запрос, который возвращает много записей, например, Person.all.each {|p| puts p.name}
, и 100 человек имеют старый формат, он сразу же выполнит 100 заданных запросов.Вместо этого вы также можете вызвать self.name = "#{self.first_name} #{self.last_name}".strip
, но это означает, что ваши данные будут перенесены только в том случае, если запись сохранена.
Общие проблемы, которые могут у вас возникнуть, состоят в том, что любые массовые запросы, такие как Person.where(:name => /Foo/).count
, не будут выполняться до тех пор, пока вседанные переносятсяТакже, если вы выполните Person.only(:name).first
, миграция завершится неудачно, потому что вы забыли включить поля first_name
и last_name
.