Отключение обратных вызовов ActiveModel - PullRequest
4 голосов
/ 14 сентября 2010

Я опубликовал статью об отключении обратных вызовов 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 повторную установку удаленного обратного вызова, плохой идеей?Как бы вы это сделали?:)

Ответы [ 3 ]

1 голос
/ 14 сентября 2010

Как насчет этого?

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
1 голос
/ 14 сентября 2010

Вы можете пропустить перед сохранением обратных вызовов и проверок, используя send, например,

user = User.new(:name=>'test')
user.send(:create_without_callbacks)
0 голосов
/ 14 декабря 2010

Ваше текущее решение кажется «опасным» в том смысле, что если обновление вызывает исключение, то обратные вызовы не возвращаются на место, что может серьезно нарушить любой запрос после него.Самомодифицирующийся код - это действительно плохая идея, если он может иметь постоянные побочные эффекты для других потоков, это немного похоже на использование глобальных переменных.

Но у меня есть кажущаяся проблема, и я искал решение вокруг васбыл лучшим, что я мог найти до сих пор.Я думаю, что Rails, возможно, потребуется добавить более элегантный способ сделать это в модуль обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...