DEV: Fix tags filter with more than 2 tag names in value not working (#21380)

Specifying more than two tag names when using the `tag:` filter was not
working because of a bug in the code where only the first two value in
the `tag:` filter was being selected.
This commit is contained in:
Alan Guo Xiang Tan 2023-05-04 15:55:31 +08:00 committed by GitHub
parent d4a2e9a740
commit d4e2f764ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 2 deletions

View File

@ -309,6 +309,7 @@ class TopicsFilter
.filter_visible(Tag, @guardian) .filter_visible(Tag, @guardian)
.where_name(tag_names) .where_name(tag_names)
.pluck(:id, :target_tag_id) .pluck(:id, :target_tag_id)
.transpose
tag_ids ||= [] tag_ids ||= []
alias_tag_ids ||= [] alias_tag_ids ||= []
@ -417,7 +418,7 @@ class TopicsFilter
def include_topics_with_all_tags(tag_ids) def include_topics_with_all_tags(tag_ids)
tag_ids.each do |tag_id| tag_ids.each do |tag_id|
sql_alias = "tt#{topic_tags_alias}" sql_alias = topic_tags_alias
@scope = @scope =
@scope.joins( @scope.joins(
@ -427,7 +428,13 @@ class TopicsFilter
end end
def include_topics_with_any_tags(tag_ids) def include_topics_with_any_tags(tag_ids)
@scope = @scope.joins(:topic_tags).where("topic_tags.tag_id IN (?)", tag_ids).distinct(:id) sql_alias = topic_tags_alias
@scope =
@scope
.joins("INNER JOIN topic_tags #{sql_alias} ON #{sql_alias}.topic_id = topics.id")
.where("#{sql_alias}.tag_id IN (?)", tag_ids)
.distinct(:id)
end end
ORDER_BY_MAPPINGS = { ORDER_BY_MAPPINGS = {

View File

@ -694,6 +694,37 @@ RSpec.describe TopicsFilter do
).to contain_exactly(topic_with_tag_and_tag2.id, topic_with_tag_and_tag2_and_tag3.id) ).to contain_exactly(topic_with_tag_and_tag2.id, topic_with_tag_and_tag2_and_tag3.id)
end end
describe "when query string is `tags:tag1,tag2,tag3`" do
it "should only return topics that are tagged with either tag1, tag2 or tag3" do
topic_with_tag3 = Fabricate(:topic, tags: [tag3])
expect(
TopicsFilter
.new(guardian: Guardian.new)
.filter_from_query_string("tags:#{tag.name},#{tag2.name},#{tag3.name}")
.pluck(:id),
).to contain_exactly(
topic_with_tag.id,
topic_with_tag_and_tag2.id,
topic_with_tag2.id,
topic_with_tag3.id,
)
end
end
describe "when query string is `tags:tag1+tag2+tag3`" do
it "should only return topics that are tagged with tag1, tag2 and tag3" do
topic_with_tag_tag2_tag3 = Fabricate(:topic, tags: [tag, tag2, tag3])
expect(
TopicsFilter
.new(guardian: Guardian.new)
.filter_from_query_string("tags:#{tag.name}+#{tag2.name}+#{tag3.name}")
.pluck(:id),
).to contain_exactly(topic_with_tag_tag2_tag3.id)
end
end
it "should only return topics that are tagged with tag1 and tag2 but not tag3 when query string is `tags:tag1 tags:tag2 -tags:tag3`" do it "should only return topics that are tagged with tag1 and tag2 but not tag3 when query string is `tags:tag1 tags:tag2 -tags:tag3`" do
topic_with_tag_and_tag2_and_tag3 = Fabricate(:topic, tags: [tag, tag2, tag3]) topic_with_tag_and_tag2_and_tag3 = Fabricate(:topic, tags: [tag, tag2, tag3])