接收Webhook更新多品牌关联联系人状态的技术求助
解决方案
问题核心是你使用的Contact.find_by(email: event['email'])仅会返回第一个匹配该邮箱的联系人记录,无法覆盖同一邮箱关联的多品牌联系人。只需修改blocked方法,找到所有同邮箱的记录并批量更新即可,以下是两种实现方式:
方式1:高效批量更新(无模型回调触发)
如果你的Contact模型不需要触发before_update/after_update这类回调,使用update_all是最优选择,直接生成SQL批量执行,性能更高:
def webhook params['_json'].each do |event| blocked(event) if event['event'].eql?('blocked') end end private def blocked(event) # 若无需依赖campaign存在即可更新,可直接删除下面两行判断 campaign = Campaign.find_by(mailjet_id: event['mj_campaign_id']) return unless campaign # 找到所有匹配邮箱的联系人,批量更新subscription状态 Contact.where(email: event['email']).update_all(subscription: false) end
方式2:逐个更新(触发模型回调/验证)
如果Contact模型有必须执行的回调或验证逻辑,需要遍历每个联系人逐个更新:
def webhook params['_json'].each do |event| blocked(event) if event['event'].eql?('blocked') end end private def blocked(event) campaign = Campaign.find_by(mailjet_id: event['mj_campaign_id']) return unless campaign # 遍历所有匹配邮箱的联系人,逐个更新(会触发回调和验证) Contact.where(email: event['email']).each do |contact| contact.update(subscription: false) # 若需跳过验证,可替换为 contact.update_attribute(:subscription, false) end end
额外提示
如果业务逻辑允许(即无论哪个品牌的campaign触发拦截事件,都要更新该邮箱的所有联系人),可以直接移除campaign相关的判断逻辑,进一步简化代码。
内容的提问来源于stack exchange,提问作者Trippes3
相关产品推荐
相关产品推荐

