运行时更改模型与mongodb / mongoid
我要在mongoid模型中添加几个字段,我知道没有使用MongoDB进行迁移但是如果我不继续删除数据库,使轨道完全“重新生成”数据库,它就不显示或使用新字段一点都没!
什么是最好的方式去这里? 有什么比放弃/重新打开mongodb更软的东西吗?
在此先感谢luca
通常,应该可以在运行时使用新字段更新旧文档。 MongoDB中不需要迁移。
您可能希望编写rake任务以使用新字段和默认值更新旧文档。
您可以通过检查默认值为零的新字段来查找这些文档。
更新
简约风格:
如果使用默认值定义新字段,则只要设置新值,就应始终使用此值:
应用程序/模型/ 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
如果您查询数据库,则应在扩展名之前获取没有此字段的文档的默认值:
(rails console)
MyModel.first #=> #
我在Ruby 1.9.2上用一个新的rails堆栈和一个当前的mongoid来测试它 – 也应该与其他堆栈一起使用。
更复杂/复杂的风格:
如果您没有设置默认值,则此新字段将为nil。
应用程序/模型/ my_model.rb
class MyModel include Mongoid::Document field :name, type: String field :data, type: String # NEW FIELD field :note, type: String end
(rails console)
MyModel.first #=> #
然后,您可以设置rake任务和迁移文件,如下例所示:
LIB /任务/ 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
运行此rake mymodel:migrate
。
这只是一个起点,您可以将其扩展为完整的mongoid迁移引擎。
task :migrate => :environment do …
是必要的,否则rake不会加载模型。
说你不需要与mongodb或mongoid进行迁移是有点荒谬的。 任何复杂的应用程序都需要不时进行重构,这可能意味着将不同文档中的字段拖入新文档中。
与迁移成为部署脚本的一部分相比,编写一个rake任务的方式不太方便且容易出错,因此始终可以在每个环境中运行。
https://github.com/adacosta/mongoid_rails_migrations将AR样式迁移带到mongoid。
您可能不那么经常需要它们,但随着应用程序的增长,您肯定会需要它们。
下面是使用mongoid和ruby mongo驱动程序的数据迁移脚本的一个很好的代码示例 – 当更新的模型不再与生产数据匹配时使用。
http://pivotallabs.com/users/lee/blog/articles/1548-mongoid-migrations-using-the-mongo-driver
我知道我们会停止使用“没有移民与mongoid”作为口号。 由于错误的原因,它会将人们转向MongoDB,而且这只是部分正确。 没有架构,是的,但仍然需要维护数据,对于MongoDB而言,IMO比RDBM更难。 选择MongoDB还有其他很好的理由,这取决于你的问题。