diff --git a/lib/good_job/filterable.rb b/lib/good_job/filterable.rb index cbc339f4e..ce5b95028 100644 --- a/lib/good_job/filterable.rb +++ b/lib/good_job/filterable.rb @@ -34,9 +34,18 @@ module Filterable next if query.blank? tsvector = "(to_tsvector('english', serialized_params) || to_tsvector('english', id::text) || to_tsvector('english', COALESCE(error, '')::text))" - where("#{tsvector} @@ to_tsquery(?)", query) - .order(sanitize_sql_for_order([Arel.sql("ts_rank(#{tsvector}, to_tsquery(?))"), query]) => 'DESC') + to_tsquery_function = database_supports_websearch_to_tsquery? ? 'websearch_to_tsquery' : 'plainto_tsquery' + where("#{tsvector} @@ #{to_tsquery_function}(?)", query) + .order(sanitize_sql_for_order([Arel.sql("ts_rank(#{tsvector}, #{to_tsquery_function}(?))"), query]) => 'DESC') end) end + + class_methods do + def database_supports_websearch_to_tsquery? + return @_database_supports_websearch_to_tsquery if defined?(@_database_supports_websearch_to_tsquery) + + @_database_supports_websearch_to_tsquery = connection.postgresql_version >= 110000 + end + end end end diff --git a/spec/engine/filters/good_job/jobs_filter_spec.rb b/spec/engine/filters/good_job/jobs_filter_spec.rb index 740f94b1c..d591b9a7c 100644 --- a/spec/engine/filters/good_job/jobs_filter_spec.rb +++ b/spec/engine/filters/good_job/jobs_filter_spec.rb @@ -85,6 +85,14 @@ it 'returns a limited set of results' do expect(filter.records.size).to eq 1 end + + describe 'Ruby namespaced query' do + before { params[:query] = 'ExampleJob::DeadError' } + + it 'returns a limited set of results' do + expect(filter.records.size).to eq 1 + end + end end end diff --git a/spec/lib/good_job/filterable_spec.rb b/spec/lib/good_job/filterable_spec.rb index 7f2ecce11..966bcfa0f 100644 --- a/spec/lib/good_job/filterable_spec.rb +++ b/spec/lib/good_job/filterable_spec.rb @@ -3,7 +3,7 @@ RSpec.describe GoodJob::Filterable do let(:model_class) { GoodJob::Execution } - let!(:execution) { model_class.create(active_job_id: SecureRandom.uuid, queue_name: "default", serialized_params: { example_key: 'example_value' }, error: "ExampleError: a message") } + let!(:execution) { model_class.create(active_job_id: SecureRandom.uuid, queue_name: "default", serialized_params: { example_key: 'example_value' }, error: "ExampleJob::ExampleError: a message") } describe '.search_test' do it 'searches serialized params' do @@ -18,6 +18,10 @@ expect(model_class.search_text('ExampleError')).to include(execution) end + it 'searches strings with colons' do + expect(model_class.search_text('ExampleJob::ExampleError')).to include(execution) + end + it 'filters out non-matching records' do expect(model_class.search_text('ghost')).to be_empty end