4

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

Mongoid::Timestampsupdated_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再次设置删除的回调是一个坏主意吗?你会怎么做?:)

4

3 回答 3

1

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

user = User.new(:name=>'test')
user.send(:create_without_callbacks)
于 2010-09-13T23:31:07.337 回答
1

这个怎么样?

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
于 2010-09-14T00:08:36.530 回答
0

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

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

于 2010-12-13T22:03:03.133 回答