0

I have a module that gets included inside an Rails Observer.

The purpose is:

  • Call on after_save and after_update a method named check_integrity
  • Call check_integrity at the end of after_save or/and after_updateif defined in the Observer.

So in short it should always call check_integrity.

I tried something that looks like the following code:

module IntegrityObserver
  extend ActiveSupport::Concern

  included do
    alias_method_chain :after_save,   :check_integrity
    alias_method_chain :after_update, :check_integrity
  end

  def check_integrity
    # do something
  end
end

class UserObserver < ActiveRecord::Observer
  include IntegrityObserver

  def after_save(object)
    # do something
  end
end

But it raise an error: activesupport-3.0.17/lib/active_support/core_ext/module/aliasing.rb:31:in alias_method': undefined method after_update' for class TaskObserver' (NameError)

Someone has any idea how I can do what I want?

Thanks!

jrichardlai
  • 3,317
  • 4
  • 21
  • 24
  • is the `include CacheObserver` line intended to be `include IntegrityObserver`? Where does TaskObserver come into it? Does including the modules *after* the `after_save` definition help matters? – x1a4 Oct 12 '12 at 01:30
  • Thanks I fixed it @x1a4, including after the after_save will work but not when the method is not defined – jrichardlai Oct 12 '12 at 01:52

3 Answers3

1

ActiveRecord already provides observer functionality to monitor the lifecycle of your models. Here is how you can register a generic observer which responds to more than one model:

class AuditObserver < ActiveRecord::Observer
  observe :account, :balance

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

In your config/application.rb file:

config.active_record.observers = :audit_observer

Check out more examples here.

skryl
  • 557
  • 4
  • 7
1

alias_method_chain doesn't work that way. If you define something like:

alias_method_chain :after_save,   :check_integrity

you'll have to define the following method:

def after_save_with_check_integrity(*args)
  # do something
  # you can call the original after_save by calling:
  # after_save_without_check_integrity(*args)
end

just be aware that the alias_method_chain use is in most cases considered a bad practice.

ChuckE
  • 5,610
  • 4
  • 31
  • 59
0

Not like models, observers don't have predefined callback methods, such as after_save, after_update. So you got an "undefined method" error.

You may do it like this,

module IntegrityObserver
  extend ActiveSupport::Concern

  def after_save(record)
    check_integrity
  end

  def after_update(record)
    check_integrity
  end

  def check_integrity
    # do something
  end
end
Yanhao
  • 5,264
  • 1
  • 22
  • 15