pg_search
pg_search copied to clipboard
How would I search against a string that has an ampersand?
For example. I have two products with the following names:
Mac & cheese
Mac and cheese
Ideally, if one were to do Product.search_by_name("mac &") or Product.search_by_name("mac and"), then both products above should be in the results
I'm not related to the development of this specific plugin, but I would be looking into the direction of making the data you store all use either one or the other. If that isn't possible you could do the following thing:
- Dynamically replacing all occurrences of "&" with "and" in a postgres select statement (https://www.postgresql.org/docs/9.3/functions-string.html is a nice place to start if you want to build such queries) while searching. this makes sure that your postgres search will always find "and"s
- wrap your
Product.search_by_name(search)in a method like so:
def self.search(raw_search_string)
refined_search_string = raw_search_string.gsub!('&', 'and')
Product.search_by_name(refined_search_string)
end
It's not perfect though :(
If this is super important and your users run into a lot of "&" issues, you could alternatively add an extra column called simplified_name that you populate in a before_save hook like so:
class Product < ApplicationRecord
include PgSearch::Model
pg_search_scope :search_by_simplified_name,
against: %[name],
using: {
tsearch: { prefix: true }
}
before_save :populate_simplified_name
def self.search_by_name(query)
simplified_name = Product.simplify_name(query)
Product.search_by_simplified_name(simplified_name)
end
# you could put this method in a helper module
def self.simplify_name(query)
return '' unless query.present?
name.gsub('&', 'and')
# Other sensitization you'd like to do
end
private
def populate_simplified_name
self.simplified_name = Product.simplify_name(name).presence
end
end