diff --git a/app/controllers/api/v2/search_controller.rb b/app/controllers/api/v2/search_controller.rb index c14cd22d7..cbd9b551d 100644 --- a/app/controllers/api/v2/search_controller.rb +++ b/app/controllers/api/v2/search_controller.rb @@ -22,7 +22,7 @@ class Api::V2::SearchController < Api::BaseController params[:q], current_account, limit_param(RESULTS_LIMIT), - search_params.merge(resolve: truthy_param?(:resolve)) + search_params.merge(resolve: truthy_param?(:resolve), exclude_unreviewed: truthy_param?(:exclude_unreviewed)) ) end diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 79d64dc3e..8e7906c73 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -369,6 +369,7 @@ const fetchComposeSuggestionsTags = throttle((dispatch, getState, token) => { q: token.slice(1), resolve: false, limit: 4, + exclude_unreviewed: true, }, }).then(({ data }) => { dispatch(readyComposeSuggestionsTags(token, data.hashtags)); diff --git a/app/models/tag.rb b/app/models/tag.rb index b52b9bc9f..9aca3983f 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -124,16 +124,15 @@ class Tag < ApplicationRecord end end - def search_for(term, limit = 5, offset = 0) + def search_for(term, limit = 5, offset = 0, options = {}) normalized_term = normalize(term.strip).mb_chars.downcase.to_s pattern = sanitize_sql_like(normalized_term) + '%' + query = Tag.listable.where(arel_table[:name].lower.matches(pattern)) + query = query.where(arel_table[:name].lower.eq(normalized_term).or(arel_table[:reviewed_at].not_eq(nil))) if options[:exclude_unreviewed] - Tag.listable - .where(arel_table[:name].lower.matches(pattern)) - .where(arel_table[:name].lower.eq(normalized_term).or(arel_table[:reviewed_at].not_eq(nil))) - .order(Arel.sql('length(name) ASC, name ASC')) - .limit(limit) - .offset(offset) + query.order(Arel.sql('length(name) ASC, name ASC')) + .limit(limit) + .offset(offset) end def find_normalized(name) diff --git a/app/services/search_service.rb b/app/services/search_service.rb index a5ba5dd11..3a498dcf4 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -60,7 +60,8 @@ class SearchService < BaseService TagSearchService.new.call( @query, limit: @limit, - offset: @offset + offset: @offset, + exclude_unreviewed: @options[:exclude_unreviewed] ) end diff --git a/app/services/tag_search_service.rb b/app/services/tag_search_service.rb index 47b0e876e..b78d65625 100644 --- a/app/services/tag_search_service.rb +++ b/app/services/tag_search_service.rb @@ -2,11 +2,12 @@ class TagSearchService < BaseService def call(query, options = {}) - @query = query.strip.gsub(/\A#/, '') - @offset = options[:offset].to_i - @limit = options[:limit].to_i + @query = query.strip.gsub(/\A#/, '') + @offset = options.delete(:offset).to_i + @limit = options.delete(:limit).to_i + @options = options - results = from_elasticsearch if Chewy.enabled? + results = from_elasticsearch if Chewy.enabled? results ||= from_database results @@ -72,12 +73,15 @@ class TagSearchService < BaseService }, } - TagsIndex.query(query).filter(filter).limit(@limit).offset(@offset).objects.compact + definition = TagsIndex.query(query) + definition = definition.filter(filter) if @options[:exclude_unreviewed] + + definition.limit(@limit).offset(@offset).objects.compact rescue Faraday::ConnectionFailed, Parslet::ParseFailed nil end def from_database - Tag.search_for(@query, @limit, @offset) + Tag.search_for(@query, @limit, @offset, @options) end end diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb index ade306ed2..739bb9cf5 100644 --- a/spec/services/search_service_spec.rb +++ b/spec/services/search_service_spec.rb @@ -77,10 +77,10 @@ describe SearchService, type: :service do it 'includes the tag in the results' do query = '#tag' tag = Tag.new - allow(Tag).to receive(:search_for).with('tag', 10, 0).and_return([tag]) + allow(Tag).to receive(:search_for).with('tag', 10, 0, exclude_unreviewed: nil).and_return([tag]) results = subject.call(query, nil, 10) - expect(Tag).to have_received(:search_for).with('tag', 10, 0) + expect(Tag).to have_received(:search_for).with('tag', 10, 0, exclude_unreviewed: nil) expect(results).to eq empty_results.merge(hashtags: [tag]) end it 'does not include tag when starts with @ character' do