don't filter tags by taggable type
Due to performance reasons we cannot use the type filter on the tags. The table for ActsAsTaggableOn is too big and too unoptimized, such that the queries time out on production. See the discussion https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19740#note_120087938 for more info.
This commit is contained in:
parent
cd063eec32
commit
022ee0c0c9
|
@ -49,7 +49,7 @@ class Admin::RunnersController < Admin::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_list
|
def tag_list
|
||||||
tags = Autocomplete::ActsAsTaggableOn::TagsFinder.new(taggable_type: Ci::Runner, params: params).execute
|
tags = Autocomplete::ActsAsTaggableOn::TagsFinder.new(params: params).execute
|
||||||
|
|
||||||
render json: ActsAsTaggableOn::TagSerializer.new.represent(tags)
|
render json: ActsAsTaggableOn::TagSerializer.new.represent(tags)
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,30 +5,19 @@ module Autocomplete
|
||||||
class TagsFinder
|
class TagsFinder
|
||||||
LIMIT = 20
|
LIMIT = 20
|
||||||
|
|
||||||
def initialize(taggable_type:, params:)
|
def initialize(params:)
|
||||||
@taggable_type = taggable_type
|
|
||||||
@params = params
|
@params = params
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
@tags = ::ActsAsTaggableOn::Tag.all
|
@tags = ::ActsAsTaggableOn::Tag.all
|
||||||
|
|
||||||
filter_by_taggable_type!
|
|
||||||
search!
|
search!
|
||||||
limit!
|
limit!
|
||||||
|
|
||||||
@tags
|
@tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_by_taggable_type!
|
|
||||||
# rubocop: disable CodeReuse/ActiveRecord
|
|
||||||
@tags = @tags
|
|
||||||
.joins(:taggings)
|
|
||||||
.where(taggings: { taggable_type: @taggable_type.name })
|
|
||||||
.distinct
|
|
||||||
# rubocop: enable CodeReuse/ActiveRecord
|
|
||||||
end
|
|
||||||
|
|
||||||
def search!
|
def search!
|
||||||
search = @params[:search]
|
search = @params[:search]
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ describe Autocomplete::ActsAsTaggableOn::TagsFinder do
|
||||||
describe '#execute' do
|
describe '#execute' do
|
||||||
context 'with empty params' do
|
context 'with empty params' do
|
||||||
it 'returns all tags' do
|
it 'returns all tags' do
|
||||||
create :ci_runner, tag_list: ['tag1']
|
ActsAsTaggableOn::Tag.create!(name: 'tag1')
|
||||||
create :ci_runner, tag_list: ['tag2']
|
ActsAsTaggableOn::Tag.create!(name: 'tag2')
|
||||||
|
|
||||||
tags = described_class.new(taggable_type: Ci::Runner, params: {}).execute.map(&:name)
|
tags = described_class.new(params: {}).execute.map(&:name)
|
||||||
|
|
||||||
expect(tags).to match_array %w(tag1 tag2)
|
expect(tags).to match_array %w(tag1 tag2)
|
||||||
end
|
end
|
||||||
|
@ -18,10 +18,10 @@ describe Autocomplete::ActsAsTaggableOn::TagsFinder do
|
||||||
context 'filter by search' do
|
context 'filter by search' do
|
||||||
context 'with an empty search term' do
|
context 'with an empty search term' do
|
||||||
it 'returns an empty collection' do
|
it 'returns an empty collection' do
|
||||||
create :ci_runner, tag_list: ['tag1']
|
ActsAsTaggableOn::Tag.create!(name: 'tag1')
|
||||||
create :ci_runner, tag_list: ['tag2']
|
ActsAsTaggableOn::Tag.create!(name: 'tag2')
|
||||||
|
|
||||||
tags = described_class.new(taggable_type: Ci::Runner, params: { search: '' }).execute.map(&:name)
|
tags = described_class.new(params: { search: '' }).execute.map(&:name)
|
||||||
|
|
||||||
expect(tags).to be_empty
|
expect(tags).to be_empty
|
||||||
end
|
end
|
||||||
|
@ -29,10 +29,10 @@ describe Autocomplete::ActsAsTaggableOn::TagsFinder do
|
||||||
|
|
||||||
context 'with a search containing 2 characters' do
|
context 'with a search containing 2 characters' do
|
||||||
it 'returns the tag that strictly matches the search term' do
|
it 'returns the tag that strictly matches the search term' do
|
||||||
create :ci_runner, tag_list: ['t1']
|
ActsAsTaggableOn::Tag.create!(name: 't1')
|
||||||
create :ci_runner, tag_list: ['t11']
|
ActsAsTaggableOn::Tag.create!(name: 't11')
|
||||||
|
|
||||||
tags = described_class.new(taggable_type: Ci::Runner, params: { search: 't1' }).execute.map(&:name)
|
tags = described_class.new(params: { search: 't1' }).execute.map(&:name)
|
||||||
|
|
||||||
expect(tags).to match_array ['t1']
|
expect(tags).to match_array ['t1']
|
||||||
end
|
end
|
||||||
|
@ -40,10 +40,10 @@ describe Autocomplete::ActsAsTaggableOn::TagsFinder do
|
||||||
|
|
||||||
context 'with a search containing 3 characters' do
|
context 'with a search containing 3 characters' do
|
||||||
it 'returns the tag that partially matches the search term' do
|
it 'returns the tag that partially matches the search term' do
|
||||||
create :ci_runner, tag_list: ['tag1']
|
ActsAsTaggableOn::Tag.create!(name: 'tag1')
|
||||||
create :ci_runner, tag_list: ['tag11']
|
ActsAsTaggableOn::Tag.create!(name: 'tag11')
|
||||||
|
|
||||||
tags = described_class.new(taggable_type: Ci::Runner, params: { search: 'ag1' }).execute.map(&:name)
|
tags = described_class.new(params: { search: 'ag1' }).execute.map(&:name)
|
||||||
|
|
||||||
expect(tags).to match_array %w(tag1 tag11)
|
expect(tags).to match_array %w(tag1 tag11)
|
||||||
end
|
end
|
||||||
|
@ -54,10 +54,10 @@ describe Autocomplete::ActsAsTaggableOn::TagsFinder do
|
||||||
it 'limits the result set by the limit constant' do
|
it 'limits the result set by the limit constant' do
|
||||||
stub_const("#{described_class}::LIMIT", 1)
|
stub_const("#{described_class}::LIMIT", 1)
|
||||||
|
|
||||||
create :ci_runner, tag_list: ['tag1']
|
ActsAsTaggableOn::Tag.create!(name: 'tag1')
|
||||||
create :ci_runner, tag_list: ['tag2']
|
ActsAsTaggableOn::Tag.create!(name: 'tag2')
|
||||||
|
|
||||||
tags = described_class.new(taggable_type: Ci::Runner, params: { search: 'tag' }).execute
|
tags = described_class.new(params: { search: 'tag' }).execute
|
||||||
|
|
||||||
expect(tags.count).to eq 1
|
expect(tags.count).to eq 1
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue