Association callbacks


#1

Hello all. I am looking for some feedback on an implementation. I’m
writing
a plugin that will log all model changes. I do not want to have to add
a
line a code for this functionality every time I create a model. Instead
I
create a table with the name _changes.

The basic stuff was easy:

  base.after_create {|model|
    model.log_create if model.has_backup_table?
  }

**also log on before_update and before_destroy

What I’m curious about is the habtm relationships. I wanted to keep
track
of when this changes as well. An example would be changing a user’s
role.

So I did this:
def self.included(base)

base.before_validation{|model|
model.class.append_habtm_callbacks if model.has_backup_table?
}

end

module ClassMethods
def append_habtm_callbacks
reflect_on_all_associations.each{ |association|
if association.macro == :has_and_belongs_to_many
#add_callback
add_callback = “before_add_for_#{association.name}”
class_inheritable_reader(add_callback.to_sym)
write_inheritable_array(add_callback.to_sym, [:log_add])
#remove_callback
remove_callback = “before_remove_for_#{association.name}”
class_inheritable_reader(remove_callback.to_sym)
write_inheritable_array(remove_callback.to_sym,
[:log_remove])
end
}
end
end#end ClassMethods

This works well and the only way I found to do this without:

  1. Didn’t want to have to require code in the model. I wanted it to be
    “smart”.
  2. Didn’t want to “alias_method” any Rails code. I thought using what’s
    available was a better approach in this case.

Thoughts?

Thanks for any feedback,
andy

p.s. Sorry for the lengthy email…tried to keep it as short as
possible.


#2

Hey Andrew!

Rails already has support for association callbacks:

You can read about it in the “association callbacks” section here:

http://api.rubyonrails.com/classes/ActiveRecord/Associations/ClassMethods.html

Ciao!
Florian