Я работаю над плагином, который будет добавлять пользователей в группу, если их адрес электронной почты совпадает с белым списком.
У меня это работает для новых пользователей с помощью:
DiscourseEvent.on(:user_created) do |user|
GroupDomain.add_to_group_if_in_whitelisted_domain(user)
end
Что я хочу сделать дальше — это перемещать пользователей в группу, если они изменят свой адрес на домен из списка. Я думал, что
DiscourseEvent.on(:user_updated) do |user|
GroupDomain.add_to_group_if_in_whitelisted_domain(user)
end
сделает своё дело, но это не так. (Затем я подумал, что если они изменят адрес электронной почты, а затем изменят что-то ещё в своей записи пользователя, это сработает, и так и есть!)
Есть ли какое-то событие, которое я могу вызвать/отслеживать (я просто дикарь), которое сработает, если изменится их адрес электронной почты?
Чем больше я об этом думаю, тем больше кажется, что отсутствие срабатывания :user_updated при изменении адреса электронной почты — это баг. До появления модели user_email изменение адреса email вызывало :user_updated.
Однако наличие UserEmail с
do
after_update :trigger_user_updated_event
и с
def trigger_user_updated_event
user = User.find(self.user_id)
DiscourseEvent.trigger(:user_updated, user)
true
end
вызывает событие чаще, чем нужно (например, при входе по ссылке из письма), а также приводит к ошибке:
PG::UniqueViolation - ERROR: duplicate key value violates unique constraint "index_group_users_on_group_id_and_user_id"
Это не так, потому что это разные модели, как вы и обнаружили. Поскольку изменения от @LeoMcA были слиты, User и UserEmail стали разными моделями, и изменение экземпляра UserEmail не вызовет срабатывание наблюдателя (watcher) в экземпляре User.
self.add_model_callback(UserEmail, :after_commit, on: :update) do
puts "#{'-'*50}\nEMAIL YES ADDRESS IS UPDATED for #{self.user_id}!!!!\n#{'-'*50}\n"
user = User.find(self.user_id)
GroupDomain.add_to_group_if_in_whitelisted_domain(user)
end