jrichardlai
jrichardlai

Reputation: 3357

Alias method chain with method not defined

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

The purpose is:

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!

Upvotes: 0

Views: 1127

Answers (3)

Yanhao
Yanhao

Reputation: 5294

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

Upvotes: 0

ChuckE
ChuckE

Reputation: 5688

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.

Upvotes: 1

skryl
skryl

Reputation: 557

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.

Upvotes: 1

Related Questions