diff --git a/lib/search_entries.rb b/lib/search_entries.rb index f199872f..ffb1dfdc 100644 --- a/lib/search_entries.rb +++ b/lib/search_entries.rb @@ -8,9 +8,9 @@ module SearchEntries module_function def reindex_all - Submitter.find_each { |submitter| index_submitter(submitter) } - Submission.find_each { |submission| index_submission(submission) } - Template.find_each { |template| index_template(template) } + Submitter.includes(:search_entry).find_each { |submitter| index_submitter(submitter) } + Submission.includes(:search_entry).find_each { |submission| index_submission(submission) } + Template.includes(:search_entry).find_each { |template| index_template(template) } end def enqueue_reindex(records) @@ -155,11 +155,9 @@ module SearchEntries entry = submitter.search_entry || submitter.build_search_entry entry.account_id = submitter.account_id - entry.tsvector, ngram = SearchEntry.connection.select_rows(sql).first + tsvector, ngram = SearchEntry.connection.select_rows(sql).first - add_hyphens(entry, values_string) - - entry.ngram = build_ngram(ngram) + assign_vectors(entry, tsvector, ngram, values_string) return if entry.tsvector.blank? @@ -191,11 +189,9 @@ module SearchEntries entry = template.search_entry || template.build_search_entry entry.account_id = template.account_id - entry.tsvector, ngram = SearchEntry.connection.select_rows(sql).first - - add_hyphens(entry, text) + tsvector, ngram = SearchEntry.connection.select_rows(sql).first - entry.ngram = build_ngram(ngram) + assign_vectors(entry, tsvector, ngram, text) return if entry.tsvector.blank? @@ -218,11 +214,9 @@ module SearchEntries entry = submission.search_entry || submission.build_search_entry entry.account_id = submission.account_id - entry.tsvector, ngram = SearchEntry.connection.select_rows(sql).first - - add_hyphens(entry, text) + tsvector, ngram = SearchEntry.connection.select_rows(sql).first - entry.ngram = build_ngram(ngram) + assign_vectors(entry, tsvector, ngram, text) return if entry.tsvector.blank? @@ -247,6 +241,22 @@ module SearchEntries entry end + def assign_vectors(entry, tsvector, ngram, text) + entry.tsvector = tsvector + + add_hyphens(entry, text) + + entry.tsvector, entry.ngram = canonicalize_tsvectors(entry.tsvector, build_ngram(ngram)) + end + + def canonicalize_tsvectors(tsvector, ngram) + sql = SearchEntry.sanitize_sql_array( + ['SELECT ?::tsvector::text, ?::tsvector::text', tsvector, ngram] + ) + + SearchEntry.connection.select_rows(sql).first + end + def build_ngram(ngram) ngrams = ngram.split(/\s(?=')/).each_with_object([]) do |item, acc| diff --git a/spec/lib/search_entries_spec.rb b/spec/lib/search_entries_spec.rb new file mode 100644 index 00000000..bcc7728f --- /dev/null +++ b/spec/lib/search_entries_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +RSpec.describe SearchEntries do + describe '.index_template' do + let(:user) { create(:user) } + + it 'does not rewrite an unchanged search entry' do + template = create( + :template, + account: user.account, + author: user, + attachment_count: 0, + name: 'Application 12-ab' + ) + + described_class.index_template(template) + search_entry = template.search_entry.reload + updated_at = search_entry.updated_at + sql = [] + + callback = lambda do |_name, _start, _finish, _id, payload| + sql << payload[:sql] + end + + ActiveSupport::Notifications.subscribed(callback, 'sql.active_record') do + described_class.index_template(template.reload) + end + + expect(search_entry.reload.updated_at).to eq(updated_at) + expect(sql.grep(/UPDATE "search_entries"/)).to be_empty + end + + it 'updates the search entry when the template name changes' do + template = create( + :template, + account: user.account, + author: user, + attachment_count: 0, + name: 'Original application' + ) + + described_class.index_template(template) + original_tsvector = template.search_entry.reload.tsvector + + template.update!(name: 'Replacement agreement') + described_class.index_template(template.reload) + + expect(template.search_entry.reload.tsvector).not_to eq(original_tsvector) + end + end +end