21

我的问题类似于这个如何跳过 ActiveRecord 回调?但是我使用的是 Mongoid 而不是 AR,似乎在当前版本的 Mongoid 中还没有实现,所以我想知道什么应该是一个优雅的解决方案来实现它。(如有必要)。

4

5 回答 5

31

是的你可以!

Mongoid 建立在 ActiveModel 之上,ActiveModel 有一个skip_callback 函数。你可以skip_callback这样使用:

# skip the callback
MyModelClass.skip_callback(:save, :before, :ensure_foo_is_not_bar)

# rescue any errors to ensure callback is restored afterwords
begin
  my_model_instance.update_attributes :foo => 'bar'
rescue
  puts "Error from 'my_model_instance.update_attributes': #{$!}"
end

# restore the callback for future calls
MyModelClass.set_callback(:save, :before, :ensure_foo_is_not_bar)

我在一个大应用程序中使用它没有问题。有关更多信息,请参阅 Jeff Kreeftmeijer 的这篇博文:

http://jeffkreftmeijer.com/2010/disabling-activemodel-callbacks/

于 2010-10-12T20:58:22.663 回答
22

使用 Mongoid 原子操作(设置、取消设置等)可能更容易:

https://docs.mongodb.com/mongoid/current/tutorials/mongoid-persistence/#atomic

这些不会触发回调。

编辑:Mongoid 3 说他们不会触发回调。我看到他们在 Mongoid 2 中触发回调。所以YMMV

于 2012-09-13T04:58:43.487 回答
15

我最终使用了布赖恩阿姆斯特朗的建议并简单地打电话

person.set(name:"Robert Pulson")

在我保存后的回调中。

于 2015-06-19T18:34:57.983 回答
3

当您想要在不触发大量项目的所有回调的情况下进行更新时,通常会出现这种情况。这可以通过下降到驱动程序来完成:

将 'x' 字段中的 'foo' 替换为 'bar'。

User.all.each do |u|
  User.collection.where({ _id: u.id }).update({ 
    "$set" => { :x => u.x.gsub('foo', 'bar') 
  })
end
于 2013-01-07T18:37:54.617 回答
1

我搜索代码。在 Mongoid 中也没有办法避免回调。在 1.9 和 2.0 版本中。

您需要为此提出补丁或功能请求。

于 2010-06-15T16:26:18.740 回答