Разработка плагинов: срабатывает ли событие при изменении адреса электронной почты?

Я работаю над плагином, который будет добавлять пользователей в группу, если их адрес электронной почты совпадает с белым списком.

У меня это работает для новых пользователей с помощью:

  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"

Несколько минут я думал, что всё понял. :crying_cat_face:

Это не так, потому что это разные модели, как вы и обнаружили. Поскольку изменения от @LeoMcA были слиты, User и UserEmail стали разными моделями, и изменение экземпляра UserEmail не вызовет срабатывание наблюдателя (watcher) в экземпляре User.

Подскажите, пожалуйста, как лучше всего вызвать функцию conditionally_add_to_group при изменении адреса электронной почты?

Думаю, что в plugin.rb достаточно сделать что-то вроде этого

after_initialize do

  add_model_callback(UserEmail, :after_commit, on: :update) do
     # Group.add blablabla
  end

end

Ура! Это работает!

  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

Огромное спасибо, @Falco!