Rails应用中如何从邮箱数组中过滤非活跃邮箱地址?
问题根因
你在each遍历数组的同时调用delete修改原数组,会导致数组实时缩容、索引移位,遍历过程会跳过后续相邻的元素,这就是只能过滤单个非活跃邮箱的原因。
你当前写的email_list.select(email)写法完全无效:Array#select需要接收块参数来判断元素是否保留,且该方法默认返回新数组不会修改原数组,原有遍历逻辑没有对email_list做任何修改,无法实现过滤效果。
正确实现
def self.delivering_email(message) return if email_to_be_delivered?(message.subject) email_list = message.to if email_list.is_a?(String) email_list = email_list.split(",").map(&:strip) end # 直接过滤符合要求的邮箱,生成新数组避免操作原数组的异常 valid_emails = email_list.select do |email| identity = Identity.find_by(email: email) # 无对应身份记录的邮箱默认保留,若需删除可调整为 identity && identity.try(:preferred_user).active? identity.nil? || identity.try(:preferred_user).active? end message.to = valid_emails message.perform_deliveries = valid_emails.any? end
优化说明
- 全程不修改遍历中的原数组,彻底规避索引错乱导致的漏过滤问题
- 过滤逻辑集中在
select块内,可读性更高,排查问题更方便 - 若使用Ruby 2.3及以上版本,可以用安全导航操作符
&.替代try,写法更简洁:identity&.preferred_user&.active?
内容的提问来源于stack exchange,提问作者Pouya
相关产品推荐
相关产品推荐

