FIX: tag input should not include tags you've already chosen in the search results

This commit is contained in:
Neil Lalonde
2018-03-13 16:34:28 -04:00
parent c75fd34328
commit 58508e553d
3 changed files with 93 additions and 37 deletions

View File

@@ -32,9 +32,13 @@ module DiscourseTagging
# guardian is explicitly nil cause we don't want to strip all
# staff tags that already passed validation
tags = filter_allowed_tags(Tag.where(name: tag_names), nil, for_input: true,
category: category,
selected_tags: tag_names).to_a
tags = filter_allowed_tags(
Tag.where(name: tag_names),
nil, # guardian
for_topic: true,
category: category,
selected_tags: tag_names
).to_a
if tags.size < tag_names.size && (category.nil? || category.tags.count == 0)
tag_names.each do |name|
@@ -57,13 +61,22 @@ module DiscourseTagging
# term: a search term to filter tags by name
# category: a Category to which the object being tagged belongs
# for_input: result is for an input field, so only show permitted tags
# for_topic: results are for tagging a topic
# selected_tags: an array of tag names that are in the current selection
def self.filter_allowed_tags(query, guardian, opts = {})
selected_tag_ids = opts[:selected_tags] ? Tag.where(name: opts[:selected_tags]).pluck(:id) : []
if opts[:for_input] && !selected_tag_ids.empty?
query = query.where('tags.id NOT IN (?)', selected_tag_ids)
end
term = opts[:term]
if term.present?
term.gsub!("_", "\\_")
term = clean_tag(term)
query = query.where('tags.name like ?', "%#{term}%")
# query = query.where('tags.id NOT IN (?)', selected_tag_ids) unless selected_tag_ids.empty?
end
# Filters for category-specific tags:
@@ -86,7 +99,7 @@ module DiscourseTagging
query = query.where("tags.id IN (SELECT tag_id FROM tag_group_memberships WHERE tag_group_id IN (?))", tag_group_ids)
end
elsif opts[:for_input] || category
elsif opts[:for_input] || opts[:for_topic] || category
# exclude tags that are restricted to other categories
if CategoryTag.exists?
query = query.where("tags.id NOT IN (SELECT tag_id FROM category_tags)")
@@ -98,9 +111,7 @@ module DiscourseTagging
end
end
if opts[:for_input]
selected_tag_ids = opts[:selected_tags] ? Tag.where(name: opts[:selected_tags]).pluck(:id) : []
if opts[:for_input] || opts[:for_topic]
unless guardian.nil? || guardian.is_staff?
staff_tag_names = SiteSetting.staff_tags.split("|")
query = query.where('tags.name NOT IN (?)', staff_tag_names) if staff_tag_names.present?