Generelt burde det være muligt at opdatere gamle dokumenter med de nye felter under kørsel. Der er ikke behov for migreringer i MongoDB.
Du vil måske skrive rake-opgaver for at opdatere dine gamle dokumenter med de nye felter og standardværdier.
Du kan finde ud af disse dokumenter ved at afkrydse de nye felter, som som standard har en nul-værdi.
Opdater
Nem stil:
Hvis du definerer et nyt felt med en standardværdi, skal denne værdi altid bruges, så længe du indstiller et nyt:
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
Hvis du forespørger i din database, skal du få din standardværdi for dokumenter, der ikke har dette felt før din udvidelse:
(skinnekonsol)
MyModel.first
#=> #<MyModel …other fields…, note: "no note given so far!">
Jeg testede dette med en frisk railstak med en aktuel mongoid på Ruby 1.9.2 - burde også fungere med andre stakke.
Mere kompliceret/kompleks stil:
Hvis du ikke har angivet en standardværdi, får du nul for dette nye felt.
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
(skinnekonsol)
MyModel.first
#=> #<MyModel …other fields…, note: nil>
Så kan du konfigurere en rake-opgave og migreringsfil som i dette eksempel:
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
Kør denne migrering med rake mymodel:migrate
.
Dette er kun et udgangspunkt, og du kan udvide dette til en fuld mongoid-migreringsmotor.
task :migrate => :environment do …
er nødvendigt, ellers vil rake ikke indlæse modeller.