我有一个用户模型,其中有一个部门字段,其默认值为“工程”。
该字段是在我们的网站上线两个月后才引入的,并且自mongo以来没有任何迁移。
当我尝试使用where获取对象时,返回正确的值
User.find_by(:name => "John).department
但是,如果我尝试使用值,它将返回nil而不是默认值。
User.limit(2).pluck(:department)
退货
[nil,"Finance"]
我进行了一些研究,发现此博客文章http://ahmadsherif.com/blog/2013/01/29/mongoid-default-fields-can-give-you-hard-time/
我认为我也面临着同样的问题。有什么解决办法吗?我选择顺其自然,因为它不占用大量内存,而且可以节省时间。
基本上,这里的行为可以通过MongoDB处理默认值与传统关系数据库(如Postgres)之间的差异来解释。
在SQL世界中,您通过数据库模式设置默认值,并且每次插入一行时,DB都会填充NULL字段。
由于MongoDB是无模式的,因此文档字段的默认值为nil,无法更改*,因为没有可在数据库级别定义默认值的模式。而是在应用程序级别上实现默认值。对于Mongoid,这意味着在初始化新的模型实例时,它将填充默认值为nil的默认值。
用ActiveRecord术语看起来像这样:
class Thing < ActiveRecord::Base
after_initialize :set_default_foo, if: -> { self.foo.nil? }
private
def set_default_foo
self.foo = "bar"
end
end
但是,如果您有现有文档并添加新字段或默认值为现有字段,则Mongoid不会为您更新现有文档!
那么这如何解释这两种情况?
User.find_by(:name => "John").department
User.limit(2).pluck(:department)
在第一种情况下,您将文档从存储中拉出并使用它来初始化模型实例。初始化模型实例后,将运行一个回调,该回调将设置默认值。
在.pluck
手上调用时,Mongoid直接从存储中提取值,而无需初始化任何模型实例。因此,对于任何“旧版”文档,它将返回nil值。
要解决此问题,您需要为任何带nil的文档设置默认值。
User.where(department: nil).update_all(department: 'engineering')
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句