mongoid pluck - 不返回模型中默认值的正确值
mongoid pluck - not returning correct values with default values in model
我有一个用户模型,其中有一个默认值为 "Engineering" 的部门字段。
该字段是我们网站上线2个月后引入的,自mongo以来,一直没有迁移。
当我尝试使用 where 获取对象时,返回了正确的值
User.find_by(:name => "John).department
但是,如果我尝试提取值,它 returns 为 nil 而不是默认值。
User.limit(2).pluck(:department)
returns
[nil,"Finance"]
我做了一些研究,发现了这个博客 post http://ahmadsherif.com/blog/2013/01/29/mongoid-default-fields-can-give-you-hard-time/
我想我也遇到了同样的问题。有什么解决方法吗?我选择了 pluck 因为它不占用内存并且节省时间。
基本上,这里的行为可以用 MongoDB 处理默认值的方式与传统关系数据库(如 Postgres)的不同来解释。
在 SQL 世界中,您通过数据库架构设置默认值,并且每次您插入一行时,数据库都会填充一个 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 直接从存储中提取值,而不初始化任何模型实例。因此,对于任何 "legacy" 文档,它将 return 为零值。
要解决此问题,您需要为任何包含 nil 的文档设置默认值。
User.where(department: nil).update_all(department: 'engineering')
我有一个用户模型,其中有一个默认值为 "Engineering" 的部门字段。
该字段是我们网站上线2个月后引入的,自mongo以来,一直没有迁移。
当我尝试使用 where 获取对象时,返回了正确的值
User.find_by(:name => "John).department
但是,如果我尝试提取值,它 returns 为 nil 而不是默认值。
User.limit(2).pluck(:department)
returns
[nil,"Finance"]
我做了一些研究,发现了这个博客 post http://ahmadsherif.com/blog/2013/01/29/mongoid-default-fields-can-give-you-hard-time/
我想我也遇到了同样的问题。有什么解决方法吗?我选择了 pluck 因为它不占用内存并且节省时间。
基本上,这里的行为可以用 MongoDB 处理默认值的方式与传统关系数据库(如 Postgres)的不同来解释。
在 SQL 世界中,您通过数据库架构设置默认值,并且每次您插入一行时,数据库都会填充一个 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 直接从存储中提取值,而不初始化任何模型实例。因此,对于任何 "legacy" 文档,它将 return 为零值。
要解决此问题,您需要为任何包含 nil 的文档设置默认值。
User.where(department: nil).update_all(department: 'engineering')