pfaffman
(Jay Pfaffman)
2019 年7 月 24 日 23:06
1
我正在开发一个插件,当用户的电子邮件地址与白名单匹配时,自动将其添加到某个用户组。
目前,我已经为新建用户实现了以下功能:
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
但实际并不起作用。(后来我发现,如果用户先修改了电子邮件地址,然后再修改用户记录中的其他内容,该逻辑就会生效!)
是否存在某个事件,可以在用户电子邮件地址被修改时触发?(我只是个新手,不太熟悉这些机制。)
pfaffman
(Jay Pfaffman)
2019 年7 月 25 日 18:32
2
我越想越觉得,当邮箱地址被更改时 :user_updated 未被触发似乎是一个 bug。在我们拥有 user_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"
有那么几分钟,我还以为自己搞懂了。
Falco
(Falco)
2019 年7 月 25 日 18:39
3
这并不是因为它们是不同的模型,正如你所发现的。由于 @LeoMcA 的更改已合并,User 和 UserEmail 现在是不同的模型,因此更改 UserEmail 的实例不会触发 User 实例中的观察者。
pfaffman
(Jay Pfaffman)
2019 年7 月 25 日 18:42
4
请问,当电子邮件地址发生变化时,调用 conditionally_add_to_group 函数的最佳方法是什么?
Falco
(Falco)
2019 年7 月 25 日 18:54
5
我觉得在 plugin.rb 中像这样写应该就可以了
after_initialize do
add_model_callback(UserEmail, :after_commit, on: :update) do
# Group.add 等等
end
end
pfaffman
(Jay Pfaffman)
2019 年7 月 25 日 19:19
6
太好了!IT 工作正常!
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 !