ruby-on-rails – Ruby on Rails和NoSQL,添加字段
我只是用Rails潜入
Mongodb和MongoID,我发现它很棒. NoSQL帮助的一件事是我可以随时添加额外的字段到我的模型而不需要任何额外的努力:
class Page include Mongoid::Document include Mongoid::MultiParameterAttributes field :title,:type => String field :body,:type => String field :excerpt,:type => String #Added later field :location,:type => String #Added later field :published_at,:type => Time validates :title,:presence => true validates :body,:presence => true validates :excerpt,:presence => true end 这应该完美无缺.但我的问题是,(对不起,如果这是微不足道的)现有条目是空白的,并且没有为新添加的字段定义的值.例如,在示例博客应用程序中,在我发布了两篇帖子之后,我决定在我的数据库中添加摘录和位置字段(请参阅上面的代码).添加这些新字段后发布的任何博客文章都可以确保为摘录字段填写值.但是在添加这两个新字段之前发布的帖子具有空值(这是可以理解的),我无法验证.有一个优雅的解决方案吗? 谢谢. 解决方法
有三种基本选择:
>更新MongoDB中的所有内容以包含摘录. (1)当你做出改变时需要一个(可能很大的)时间命中,但这只是一次性的事情,之后你不必担心它.你将每个页面拉出MongoDB,执行page.excerpt =’some default excerpt’,然后将其保存回MongoDB.如果你有很多页面,你会想要一次处理它们,例如100个.如果你这样做,你将能够搜索摘录而不必担心你应该用null做什么.您也可以通过发送JavaScript fragment into MongoDB在MongoDB中执行此操作: connection.eval(%q{ db.pages.find({},{ _id: true }).forEach(function(p) { db.pages.update( { _id: p._id },{ $set: { excerpt: 'some default excerpt' } } ); }); }) (2)会是这样的: after_initialize :add_default_excerpt,:unless => :new_record? #... private def add_default_excerpt self.excerpt = 'some default excerpt' unless self.excerpt.present? end 您可以将除非self.excerpt移动到:除非您不介意使用lambda: after_initialize :add_default_excerpt,:unless => ->{ |o| o.new_record? || o.excerpt.present? } #... private def add_default_excerpt self.excerpt = 'some default excerpt' end 这应该是非常快速和容易设置,但有缺点.首先,你在MongoDB中有一堆空值,你可能需要在搜索过程中特别对待它们.此外,您将携带一堆代码和逻辑来处理旧数据,但随着时间的推移,这件行李的使用会越来越少.此外,after_initialize调用不是免费的. (3)要求你跳过验证非新页面摘录的存在(:除非=>:new_record?)或者你必须找到一些方法来区分新对象和旧对象,同时还要正确处理新旧页面.您还可以强制人们在更改页面时提供摘录并按原样保留验证;包括a:default => ”在你的领域:摘录将处理意见等中的任何零问题. 如果可能的话,我会去(1).如果更新花费的时间太长而且您希望在修复MongoDB时启动并运行该网站,则可以添加:default => ”更新然后删除:default选项,重新启动,并手动修补任何通过的故障. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |