Я работаю с внешней структурой (redmine), которая имеет одну Project
модель, которая имеет_many EnabledModules
.
Проекты могут иметь EnabledModules, «прикрепленные» или «удаленные» через имена модулей, например:
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
Я хотел бы определить, когда новые модули подключаются / удаляются с помощью обратных вызовов на EnabledModule
, и не изменять «исходный код», если это возможно.
Я могу обнаружить «вложения», например:
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
Я думал, что before_destroy
будет работать для обнаружения удалений, но не будет.
Это происходит потому, что вызов enabled_modules.clear
для Project.enabled_module_names=
не вызывает 'destroy' для модулей. Он просто устанавливает их project_id
на ноль. Поэтому я решил, что должен использовать after_update
или before_update
.
Если я использую after_update
, как я могу получить «предыдущий» project_id
?
Если я использую before_update
, как я могу провести различие между модулями, которые «только что обновлены», и модулями, чей project_id будет сброшен на ноль?
Должен ли я использовать здесь совершенно другой подход?
РЕДАКТИРОВАТЬ: Я просто обнаружил , что я могу получить старые значения с помощью '_was' (т.е. self.project_was
). Однако, collection.clear
, похоже, не запускает обратные вызовы обновления. Любые другие решения?
РЕДАКТИРОВАТЬ 2: Изменение названия