FIX: tag input doesn't show all top 5 permitted tags

This commit is contained in:
Neil Lalonde 2019-12-10 10:19:03 -05:00
parent 2605adede0
commit 20464116ae
3 changed files with 31 additions and 9 deletions

View File

@ -216,7 +216,7 @@ class TagsController < ::ApplicationController
filter_params[:term] = clean_name
filter_params[:order_search_results] = true
else
filter_params[:order] = "topic_count DESC"
filter_params[:order_popularity] = true
end
tags_with_counts = DiscourseTagging.filter_allowed_tags(

View File

@ -151,7 +151,7 @@ module DiscourseTagging
TAG_GROUP_RESTRICTIONS_SQL ||= <<~SQL
tag_group_restrictions AS (
SELECT t.name as tag_name, t.id as tag_id, tgm.id as tgm_id, tg.id as tag_group_id, tg.parent_tag_id as parent_tag_id,
SELECT t.id as tag_id, tgm.id as tgm_id, tg.id as tag_group_id, tg.parent_tag_id as parent_tag_id,
tg.one_per_topic as one_per_topic
FROM tags t
LEFT OUTER JOIN tag_group_memberships tgm ON tgm.tag_id = t.id /*and_name_like*/
@ -161,13 +161,13 @@ module DiscourseTagging
CATEGORY_RESTRICTIONS_SQL ||= <<~SQL
category_restrictions AS (
SELECT t.name as tag_name, t.id as tag_id, ct.id as ct_id, ct.category_id as category_id
SELECT t.id as tag_id, ct.id as ct_id, ct.category_id as category_id
FROM tags t
INNER JOIN category_tags ct ON t.id = ct.tag_id /*and_name_like*/
UNION
SELECT t.name as tag_name, t.id as tag_id, ctg.id as ctg_id, ctg.category_id as category_id
SELECT t.id as tag_id, ctg.id as ctg_id, ctg.category_id as category_id
FROM tags t
INNER JOIN tag_group_memberships tgm ON tgm.tag_id = t.id /*and_name_like*/
INNER JOIN category_tag_groups ctg ON tgm.tag_group_id = ctg.tag_group_id
@ -189,7 +189,6 @@ module DiscourseTagging
# Options:
# term: a search term to filter tags by name
# order: order by for the query
# limit: max number of results
# category: a Category to which the object being tagged belongs
# for_input: result is for an input field, so only show permitted tags
@ -197,6 +196,8 @@ module DiscourseTagging
# selected_tags: an array of tag names that are in the current selection
# only_tag_names: limit results to tags with these names
# exclude_synonyms: exclude synonyms from results
# order_search_results: result should be ordered for name search results
# order_popularity: order result by topic_count
def self.filter_allowed_tags(guardian, opts = {})
selected_tag_ids = opts[:selected_tags] ? Tag.where_name(opts[:selected_tags]).pluck(:id) : []
category = opts[:category]
@ -219,8 +220,16 @@ module DiscourseTagging
outer_join = category.nil? || category.allow_global_tags || !category_has_restricted_tags
distinct_clause = if opts[:order_popularity]
"DISTINCT ON (topic_count, name)"
elsif opts[:order_search_results]
"DISTINCT ON (lower(name) = lower(:cleaned_term), topic_count, name)"
else
""
end
sql << <<~SQL
SELECT t.id, t.name, t.topic_count, t.pm_topic_count,
SELECT #{distinct_clause} t.id, t.name, t.topic_count, t.pm_topic_count,
tgr.tgm_id as tgm_id, tgr.tag_group_id as tag_group_id, tgr.parent_tag_id as parent_tag_id,
tgr.one_per_topic as one_per_topic, t.target_tag_id
FROM tags t
@ -323,10 +332,10 @@ module DiscourseTagging
end
builder.limit(opts[:limit]) if opts[:limit]
if opts[:order]
builder.order_by(opts[:order])
if opts[:order_popularity]
builder.order_by("topic_count DESC, name")
elsif opts[:order_search_results] && !term.blank?
builder.order_by("lower(name) = lower(:cleaned_term) DESC, topic_count DESC")
builder.order_by("lower(name) = lower(:cleaned_term) DESC, topic_count DESC, name")
end
result = builder.query(builder_params).uniq { |t| t.id }

View File

@ -617,6 +617,19 @@ describe TagsController do
json = get_json_body
expect(json["results"].map { |j| j["id"] }).to eq(['тема-в-разработке'])
end
it "can return all the results" do
tag_group1 = Fabricate(:tag_group, tag_names: ['common1', 'common2', 'group1tag', 'group1tag2'])
tag_group2 = Fabricate(:tag_group, tag_names: ['common1', 'common2'])
category = Fabricate(:category, tag_groups: [tag_group1])
get "/tags/filter/search.json", params: { q: '', limit: 5, categoryId: category.id, filterForInput: 'true' }
expect(response.status).to eq(200)
json = get_json_body
expect_same_tag_names(
json["results"].map { |j| j["id"] },
['common1', 'common2', 'group1tag', 'group1tag2']
)
end
end
end