ActiveRecord Глобальные обратные вызовы для всех моделей - PullRequest
6 голосов
/ 12 октября 2010

У меня около 40 моделей в моем приложении RoR. Я хочу настроить обратный вызов after_save для всех моделей. Один из способов - добавить его ко всем моделям. Поскольку для этого обратного вызова используется один и тот же код, существует ли способ однократно его определить глобально, чтобы он вызывался для всех моделей.

Я попробовал это без удачи:

class ActiveRecord::Base

  after_save :do_something

  def do_something
    # .... 
  end
end

Тот же код работает, если я делаю это в отдельных моделях.

Спасибо, Имран

Ответы [ 5 ]

9 голосов
/ 12 октября 2010

Для этого следует использовать наблюдателей:

class AuditObserver < ActiveRecord::Observer      

  observe ActiveRecord::Base.send(:subclasses)

  def after_save(record)
    AuditTrail.new(record, "UPDATED")
  end
end

Чтобы активировать наблюдателя, укажите его в настройке конфигурации config.active_record.observers в файле config / application.rb.1005 *

Примечание

В Rails 4 функция наблюдателя удалена из ядра.Используйте драгоценный камень https://github.com/rails/rails-observers.

4 голосов
/ 04 мая 2012

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

Некоторые модели могут не загружаться, когда загружен наблюдатель.В документации сказано, что вы можете переопределить наблюдаемые классы, и таким образом вы можете динамически получать подклассы активной записи.

class AuditObserver < ActiveRecord::Observer
  def self.observed_classes                 
    ActiveRecord::Base.send(:subclasses)    
  end
end
1 голос
/ 10 декабря 2014

На основании ответа @ harish и в этом ответе (https://stackoverflow.com/a/10712838/2226338):

class AuditObserver < ActiveRecord::Observer
    Rails.application.eager_load!
    observe ActiveRecord::Base.descendants

    def after_save(record)
        ...
    end
end
1 голос
/ 04 февраля 2014

Мне показалось, что это работает:

ActiveRecord::Base.after_save do
   ...
end

Есть ли проблема, которую я не вижу?

0 голосов
/ 29 сентября 2012

На самом деле это хорошо работает в 2.3.8:

class AudiObserver < ActiveRecord::Observer
  observe :'ActiveRecord::Base'
  #
  # observe methods...
  #
end
...