运行时更改模型与mongodb / mongoid

时间:2011-07-17 14:35:11

标签: ruby mongodb migration mongoid nosql

我要在mongoid模型中添加几个字段,我知道没有MongoDB的迁移但是如果我继续而不删除数据库,使得rails完全“重新生成”数据库,它不会显示或使用新的领域!

去哪里最好的方法是什么?有什么比放弃/重新打开mongodb更软的东西吗?

提前致谢 卢卡

3 个答案:

答案 0 :(得分:11)

通常,应该可以在运行时使用新字段更新旧文档。 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
#=> #<MyModel …other fields…, note: "no note given so far!">

我在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
#=> #<MyModel …other fields…, note: nil>

然后您可以设置一个rake任务和迁移文件,如下例所示:

LIB /任务/ 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 …是必要的,否则rake不会加载模型。

答案 1 :(得分:4)

说你不需要与mongodb或mongoid进行迁移是有点荒谬的。任何复杂的应用程序都需要不时进行重构,这可能意味着将不同文档中的字段拖入新文档中。

编写一个rake rake任务比将迁移作为部署脚本的一部分更方便,更容易出错,因此它总是在每个环境中运行。

https://github.com/adacosta/mongoid_rails_migrations将AR风格的迁移带到了mongoid。

您可能不太经常需要它们,但随着应用程序的增长,您肯定会需要它们。

答案 2 :(得分:1)

以下是使用mongoid和ruby mongo驱动程序的数据迁移脚本的一个很好的代码示例 - 当更新的模型不再与生产数据匹配时使用。

http://pivotallabs.com/users/lee/blog/articles/1548-mongoid-migrations-using-the-mongo-driver

我希望我们停止使用&#34;没有以mongoid&#34; 作为口号进行迁移。它会因为错误的原因将人们转为MongoDB,而且只是部分正确。没有架构,是的,但是仍然需要维护数据,对于MongoDB而言,IMO比RDBM更难。选择MongoDB还有其他很好的理由,这取决于你的问题。