Пользовательские обратные вызовы с наблюдателем в рельсах3 - PullRequest
5 голосов
/ 21 февраля 2011

Я в отчаянии от одной проблемы.

я хочу зарегистрировать пользовательский обратный вызов: after_something а затем использовать этот обратный вызов в наблюдателя.

Я пробовал с define_callbacks, set_callbacks, но наблюдатель никогда не запускает этот обратный вызов.

Я знаю, что могу использовать обратные вызовы AR, но в некоторых ситуациях я предпочитаю использовать свои собственные обратные вызовы.

Спасибо

Ответы [ 3 ]

17 голосов
/ 22 февраля 2011

Вот решение, если кто-то ищет:

в вашей модели, вызовите это:

notify_observers(:after_my_custom_callback)

В вашем наблюдателе просто определите метод:

def after_my_custom_callback(record)

 #do things
end
1 голос
/ 27 января 2012

Благодаря ответу Алекса я смог решить эту проблему, определив метод define_model_callbacks_for_observers, который следует вызывать вместо define_model_callbacks (вы можете поместить его в модуль):

def define_model_callbacks_for_observers(*args)
  types = Array.wrap(args.extract_options![:only] || [:before, :around, :after])

  callbacks = define_model_callbacks(*args)

  callbacks.each do |callback|
    types.each do |filter|
      set_callback(callback, filter) do
        notify_observers :"#{filter}_#{callback}"
        true
      end
    end
  end
end
1 голос
/ 21 февраля 2011

Обозреватель использует стандартные обратные вызовы AR, поэтому он не вызовет ваш стандартный ответ по умолчанию.

Я думаю, что, скорее, придумывая новый обратный вызов (и поведение AR по умолчанию для monkeypatch AR), возможно, вам следует использовать AR.Сложно сказать что ты хочешь.Можете ли вы привести пример использования?

попробуйте, может быть, что-то вроде

before_save MyCallbacks.new, :if => :some_condiditons_meet?

class MyCallbacks
  def before_save(object)
    sophistcated_use(object) if object.valid?
    damn_have_it?
  end
end

, оно на самом деле охватывает поведение наблюдателя на каком-то уровне

<- update ->

Вся цепочка обратного вызова вызова save, save !, или destroy выполняется внутри транзакции.Это включает в себя after_ * хуки.Если все идет хорошо, команда COMMIT выполняется после того, как цепочка была завершена.

Я думаю, что вся идея ОДНОГО наблюдателя - не лучшее решение.После того, как появится больше зависимостей, ваша логика будет очень сложной.Определение собственных оболочек транзакций - это хорошо, но вам это действительно нужно?Возможно, вы можете изменить модель для достижения этой цели, не записывая собственный случай транзакции.

Например,

class Friendship < ActiveRecord::Base
  belongs_to :user
  has_many :users, :through => :groups

  after_validation :save_my_records

  def save_my_records
    user.friend.history.save
    user.history.save
  end

end

Где друг - это объект => есть собственный наблюдатель, а история - это объект => естьсобственный наблюдатель

Это очень абстрактно, но без вашего кода я понятия не имел, как привести какой-то конструктивный пример, также after_validation - не лучшее место для сохранения чего-либо, я думаю.

также notify_observer звучит как хакмне: -)

...