4

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のは悪い考えですか?これをどのように行いますか?:)

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 に答える