禁用 ActiveModel 回调

发布于 2024-09-18 14:43:37 字数 748 浏览 2 评论 0原文

我发表了一篇关于禁用 ActiveModel 回调的文章,但我不完全确定这一点是做这样的事情最漂亮的方式。

Mongoid::Timestamps 添加了一个更新 updated_at 字段的保存前回调。假设在某些情况下我不希望出现这种情况,并且我像这样禁用回调:

class User
  # I'm using Mongoid, but this should work for anything based on 
  # ActiveModel.
  include Mongoid::Document
  include Mongoid::Timestamps

  def sneaky_update(attributes)
    User.skip_callback(:save, :before, :set_updated_at)
    User.update_attributes(attributes)
    User.set_callback(:save, :before, :set_updated_at)
  end

end

调用 skip_callback 后跟 set_callback 再次设置已删除的回调是一个坏主意吗?你会怎么做? :)

I published an article on disabling ActiveModel callbacks, but I’m not completely sure this is the prettiest way to do something like this.

Mongoid::Timestamps adds a before save callback that updates the updated_at field. Let's say I don't want that in some cases and I disable the callback like this:

class User
  # I'm using Mongoid, but this should work for anything based on 
  # ActiveModel.
  include Mongoid::Document
  include Mongoid::Timestamps

  def sneaky_update(attributes)
    User.skip_callback(:save, :before, :set_updated_at)
    User.update_attributes(attributes)
    User.set_callback(:save, :before, :set_updated_at)
  end

end

Is calling skip_callback followed by set_callback to set the removed callback again a bad idea? How would you do this? :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沦落红尘 2024-09-25 14:43:37

这个怎么样?

module Mongoid
  module Timestamps
    attr_accessor :skip_updated_at

    def set_updated_at_new
      unless self.skip_updated_at
        set_updated_at_org
      end
    end

    alias set_updated_at_org set_updated_at
    alias set_updated_at set_updated_at_new
  end
end

class User
  # I'm using Mongoid, but this should work for anything based on 
  # ActiveModel.
  include Mongoid::Document
  include Mongoid::Timestamps

  def sneaky_update(attributes)
    self.skip_updated_at = true
    User.update_attributes(attributes)
    self.skip_updated_at = false
  end

end

How about this?

module Mongoid
  module Timestamps
    attr_accessor :skip_updated_at

    def set_updated_at_new
      unless self.skip_updated_at
        set_updated_at_org
      end
    end

    alias set_updated_at_org set_updated_at
    alias set_updated_at set_updated_at_new
  end
end

class User
  # I'm using Mongoid, but this should work for anything based on 
  # ActiveModel.
  include Mongoid::Document
  include Mongoid::Timestamps

  def sneaky_update(attributes)
    self.skip_updated_at = true
    User.update_attributes(attributes)
    self.skip_updated_at = false
  end

end
蘑菇王子 2024-09-25 14:43:37

例如,您可以使用 send 在保存回调和验证之前跳过

user = User.new(:name=>'test')
user.send(:create_without_callbacks)

You can skip before save callbacks and validations by using send, for example

user = User.new(:name=>'test')
user.send(:create_without_callbacks)
手长情犹 2024-09-25 14:43:37

您当前的解决方案似乎“危险”,因为如果更新引发异常,则回调不会放回原位,这可能会严重破坏其后的任何请求。如果自修改代码会对其他线程产生持久的副作用,那么它是一个非常糟糕的主意,这有点像使用全局变量。

但我似乎遇到了问题,我一直在寻找解决方案,而你的解决方案是我迄今为止能找到的最好的解决方案。我认为 Rails 可能需要向 Callback 模块添加一种更优雅的方式来执行此操作。

Your current solution seems "dangerous" in that if the update raises an exception then the callbacks don't get put back into place which could seriously break any request after it. Self modifying code is a really bad idea if it can have persistent side effects for other threads, it's a bit like using globals.

But I have the seem problem and I have been looking all around for a solution and yours has been the best I could find until now. I think Rails may need to add a more elegant way to do this to the Callback module.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文