From fcb2f68565375d29b75919084f95708f6ca32c22 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Tue, 4 Jul 2017 16:12:10 -0400 Subject: [PATCH] FIX: duplicate topics and posts in summary email because user has muted tags and topics contain multiple tags --- app/models/topic.rb | 7 +++++-- spec/models/topic_spec.rb | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/models/topic.rb b/app/models/topic.rb index 40f6fea8c5c..f9fcfadf52e 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -372,8 +372,11 @@ class Topic < ActiveRecord::Base # Remove muted tags muted_tag_ids = TagUser.lookup(user, :muted).pluck(:tag_id) unless muted_tag_ids.empty? - topics = topics.joins("LEFT OUTER JOIN topic_tags ON topic_tags.topic_id = topics.id") - .where("topic_tags.tag_id NOT IN (?) OR topic_tags.tag_id is null", muted_tag_ids) + # If multiple tags per topic, include topics with tags that aren't muted, + # and don't forget untagged topics. + topics = topics.where( + "EXISTS ( SELECT 1 FROM topic_tags WHERE topic_tags.topic_id = topics.id AND tag_id NOT IN (?) ) + OR NOT EXISTS (SELECT 1 FROM topic_tags WHERE topic_tags.topic_id = topics.id)", muted_tag_ids) end topics diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb index 385bb3cfaff..b1610f60783 100644 --- a/spec/models/topic_spec.rb +++ b/spec/models/topic_spec.rb @@ -1415,13 +1415,15 @@ describe Topic do it "returns topics with no tags too" do user = Fabricate(:user) - muted_tag, other_tag = Fabricate(:tag), Fabricate(:tag) + muted_tag = Fabricate(:tag) TagUser.change(user.id, muted_tag.id, TagUser.notification_levels[:muted]) topic1 = Fabricate(:topic, tags: [muted_tag]) - topic2 = Fabricate(:topic, tags: [other_tag]) + topic2 = Fabricate(:topic, tags: [Fabricate(:tag), Fabricate(:tag)]) topic3 = Fabricate(:topic) - expect(Topic.for_digest(user, 1.year.ago, top_order: true)).to contain_exactly(topic2, topic3) + topics = Topic.for_digest(user, 1.year.ago, top_order: true) + expect(topics.size).to eq(2) + expect(topics).to contain_exactly(topic2, topic3) end it "sorts by category notification levels" do