Ruby on rails 为什么Mongoid';s";“在场”;验证是否启用自动保存?

Ruby on rails 为什么Mongoid';s";“在场”;验证是否启用自动保存?,ruby-on-rails,validation,mongoid,autosave,Ruby On Rails,Validation,Mongoid,Autosave,我很难调试这个,我正要寻求帮助。但我已经设法找出了原因,并想与大家分享我的发现,以防其他人遇到同样的问题。[也许有人能解释为什么它会这样工作] 安装程序 假设我有两个Mongoid文档,Customer和Order,它们之间的关系为1:n。此外,Customer在保存后有一个回调,用于将文档更改与外部API同步: class Customer include Mongoid::Document has_many :orders after_save do puts "sync

我很难调试这个,我正要寻求帮助。但我已经设法找出了原因,并想与大家分享我的发现,以防其他人遇到同样的问题。[也许有人能解释为什么它会这样工作]

安装程序 假设我有两个Mongoid文档,
Customer
Order
,它们之间的关系为1:n。此外,
Customer
在保存后有一个
回调,用于将文档更改与外部API同步:

class Customer
  include Mongoid::Document
  has_many :orders
  after_save do
    puts "synchronizing customer" # <- not my actual code
  end
end

class Order
  include Mongoid::Document
  belongs_to :customer
  validates_presence_of :customer
end
问题 但是突然之间,事情变得很奇怪。此更改后,创建(或更新)订单也会保存客户!(我注意到这一点是因为我的日志——同步运行没有明显的原因)

它是通过状态验证启用的,事实上,Mongoid随意地指出:

请注意,当使用
接受
的嵌套属性或验证关系的存在时,自动保存功能将自动添加到关系中

但是
autosave
仅在文档更改时保存文档,那么更改从何而来?显然,我新的带有默认值的
premium
字段引入了一个微妙的变化:

c = Customer.first # a customer from before the change without "premium" attribute
c.changed?
#=> true
c.changes
#=> {"premium"=>[nil, false]}
解决方案 毕竟,修复是相当琐碎的。我只需在我的
所属关系上显式禁用autosave即可:

class Order
  include Mongoid::Document
  belongs_to :customer, autosave: false
  validates_presence_of :customer
end
开放性问题
但问题依然存在:为什么Mongoid的“存在”验证支持autosave?这怎么可能是期望的默认行为?请告诉我。

看来自动保存的自动启用是故意添加到Mongoid 3.0中的,以便其行为与ActiveRecord一致。看看这两个问题:

第二个问题链接到一个似乎确实以同样方式表现的问题,让我们特别引用以下声明:

请注意,
autosave:false
与不声明
:autosave
不同。当
:autosave
选项不存在时,会保存新的关联记录,但不会保存更新的关联记录

下面是Mongoid特性本身的一个例子

此外,从所有这些来源可以看出,您的解决方案是完美的,您确实应该特别声明
:autosave=>false
以禁用此功能

Order.relations['customer'].autosave?
#=> true
c = Customer.first # a customer from before the change without "premium" attribute
c.changed?
#=> true
c.changes
#=> {"premium"=>[nil, false]}
class Order
  include Mongoid::Document
  belongs_to :customer, autosave: false
  validates_presence_of :customer
end