autocomplete: rework tag autocomplete behavior.
Reworks tag autocomplete to work the same way for all users. Previously autocomplete for Builders worked differently than autocomplete for regular users. This is how it works now: * If the search starts with a slash (/), then do a tag abbreviation match. For example, `/evth` matches eyebrows_visible_through_hair. * Otherwise if the search contains a wildcard (*), then just do a simple wildcard search. * Otherwise do a tag prefix match against tags and aliases. For example, `black` matches all tags or aliases beginning with `black`. * If the tag prefix match returns no results, then do a autocorrect match. The differences for regular users: * You can abbreviate tags with a slash (/). The differences for Builders: * Now tag abbreviations have to start with a slash (/). * Autocorrect isn't performed unless a regular search returns no results. * Results are always sorted by tag count. Before different types of results (regular tag matches, alias matches, abbreviation matches, and autocorrect matches) were all mixed together based on a tag weighting scheme.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
class Tag < ApplicationRecord
|
||||
ABBREVIATION_REGEXP = /([a-z0-9])[a-z0-9']*($|[^a-z0-9']+)/
|
||||
|
||||
has_one :wiki_page, :foreign_key => "title", :primary_key => "name"
|
||||
has_one :artist, :foreign_key => "name", :primary_key => "name"
|
||||
has_one :antecedent_alias, -> {active}, :class_name => "TagAlias", :foreign_key => "antecedent_name", :primary_key => "name"
|
||||
@@ -249,7 +251,7 @@ class Tag < ApplicationRecord
|
||||
end
|
||||
|
||||
def alias_matches(name)
|
||||
where(name: TagAlias.active.where_ilike(:antecedent_name, normalize_name(name)).select(:consequent_name))
|
||||
where(name: TagAlias.active.where_like(:antecedent_name, normalize_name(name)).select(:consequent_name))
|
||||
end
|
||||
|
||||
def name_or_alias_matches(name)
|
||||
@@ -260,6 +262,11 @@ class Tag < ApplicationRecord
|
||||
nonempty.name_matches(tag).order(post_count: :desc, name: :asc).limit(limit).pluck(:name)
|
||||
end
|
||||
|
||||
def abbreviation_matches(abbrev)
|
||||
abbrev = abbrev.delete_prefix("/")
|
||||
where("regexp_replace(tags.name, ?, '\\1', 'g') LIKE ?", ABBREVIATION_REGEXP.source, abbrev.to_escaped_for_sql_like)
|
||||
end
|
||||
|
||||
def search(params)
|
||||
q = super
|
||||
|
||||
@@ -352,6 +359,18 @@ class Tag < ApplicationRecord
|
||||
Post.system_tag_match(name)
|
||||
end
|
||||
|
||||
def abbreviation
|
||||
name.gsub(ABBREVIATION_REGEXP, "\\1")
|
||||
end
|
||||
|
||||
def tag_alias_for_pattern(pattern)
|
||||
return nil if pattern.blank?
|
||||
|
||||
consequent_aliases.find do |tag_alias|
|
||||
!name.ilike?(pattern) && tag_alias.antecedent_name.ilike?(pattern)
|
||||
end
|
||||
end
|
||||
|
||||
def self.model_restriction(table)
|
||||
super.where(table[:post_count].gt(0))
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user