【问题标题】:How to skip callbacks on Mongoid Documents?如何跳过 Mongoid 文档的回调?
【发布时间】:2011-03-04 01:54:55
【问题描述】:

我的问题与How to skip ActiveRecord callbacks? 类似,但我使用的是 Mongoid 而不是 AR,似乎在当前版本的 Mongoid 中还没有实现,所以我想知道应该是什么优雅的解决方案来实现它。 (如有必要)。

【问题讨论】:

  • 哪个版本的 Mongoid ? Mongoid 1.9.0 还是 Mongoid 2.0.0.beta ?

标签: ruby-on-rails ruby activerecord mongoid


【解决方案1】:

是的,你可以!

Mongoid 基于 ActiveModel 构建,ActiveModel 有一个skip_callback function。你可以像这样使用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://jeffkreeftmeijer.com/2010/disabling-activemodel-callbacks/

【讨论】:

  • 如果有一种方法可以像关闭验证一样关闭所有回调,那就太好了:u.save!(validate: false) 将是 u.save!(callbacks: false)
  • 非常感谢,这项工作适用于我的测试套件中的跳过回调。
  • 这可能会导致一个非常大的问题。如果skip_callbackset_callback 之间的代码产生了一些错误,回调可以被永远跳过并且不再设置。需要重新启动服务器才能使其再次工作。最糟糕的是:整个班级都将跳过此回调!这意味着该类的所有实例都将跳过此回调!如果你想使用它,请小心。在使用这种方法处理 skipset 回调时,我的应用程序遇到了大问题。
  • 感谢 Victor 指出这个问题。我已经更新了答案中的代码以使用 resuce 块来防止错误禁用回调。
【解决方案2】:

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

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

这些不会触发回调。

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

【讨论】:

  • 这也适用于 Mongoid 4。试图弄清楚如何在父文档中添加一个计数器,并将级联回调设置为 true。
【解决方案3】:

我最终使用了 Brian Armstrong 的建议并简单地调用了

person.set(name:"Robert Pulson")

在我的保存后回调中。

【讨论】:

    【解决方案4】:

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

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

    User.all.each do |u|
      User.collection.where({ _id: u.id }).update({ 
        "$set" => { :x => u.x.gsub('foo', 'bar') 
      })
    end
    

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

      • 谢谢,是的,我也在审查 2.0.0.beta 并且没有跳过回调支持......让我们看看 AR 是如何做到的,然后在我的 mongoid 版本上实现它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 2010-11-23
      相关资源
      最近更新 更多