I'm working with an external framework (redmine) which has one Project model that has_many EnabledModules.
Projects can have EnabledModules "attached" or "removed" via the module names, like this:
class Project < ActiveRecord::Base
...
has_many :enabled_modules, :dependent => :delete_all
...
def enabled_module_names=(module_names)
enabled_modules.clear
module_names = [] unless module_names && module_names.is_a?(Array)
module_names.each do |name|
enabled_modules << EnabledModule.new(:name => name.to_s)
end
end
end
I'd like to detect when new modules are attached/removed via callbacks on EnabledModule, and not modify the "original source code" if possible.
I can detect "attachments" like this:
class EnabledModule < ActiveRecord::Base
belongs_to :project
after_create :module_created
def module_created
logger.log("Module attached to project #{self.project_id}")
end
end
I thought that a before_destroy would work for detecting removals, but it will not.
This happens because the enabled_modules.clear call on Project.enabled_module_names=, doesn't invoke 'destroy' on the modules. It just sets their project_id to nil. So I figured I should use a after_update or before_update.
If I use after_update, how can I get the 'previous' project_id?
If I use before_update, how can I differentiate between modules that are 'just updated' and modules whose project_id is going to be reset to nil?
Should I use a totally different approach here?
EDIT: I just found out that I could get the old values with '_was' (i.e. self.project_was). However, collection.clear doesn't seem to trigger update callbacks. Any other solutions?
EDIT 2: Changed title