frontcodelover
frontcodelover

Reputation: 337

Ignore uppercase, downcase and accent in search

I have a search system with filter here. This system work like a charm but I have some problem with downcase / uppercase and accent.

For example if I search "marée" I have result but if I search "MAREE" or "Marée" or "maree". I don't have result.

I want to fix that. How I can fix this ? Thank you.

my controller

    def resultnohome
          if params[:query].blank?
            redirect_to action: :index and return
          else
          @campings = Camping.searchi(params[:query], params[:handicap], params[:animaux], params[:television], params[:plage], params[:etang], params[:lac])
            if params[:query] == "aube"
              @pub = Camping.find_by_id(1)
            else
            end
        end
end

My model

 def self.searchi(query, handicap, animaux, television, plage, etang, lac)
    return scoped unless query.present?
         result = left_outer_joins(:caracteristiquetests, :situations).where('nomdep LIKE ? OR name LIKE ? OR nomregion LIKE ? OR commune LIKE?', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%")
         result = result.where('handicap LIKE ?', "%#{handicap}%") if handicap
         result = result.where('animaux LIKE ?', "%#{animaux}%") if animaux
         result = result.where('television LIKE ?', "%#{television}%") if television
         result = result.where('plage LIKE ?', "%#{plage}%") if plage
         result = result.where('etang LIKE ?', "%#{etang}%") if etang
         result = result.where('lac LIKE ?', "%#{lac}%") if lac
      return result
  end

Upvotes: 1

Views: 1343

Answers (1)

SteveTurczyn
SteveTurczyn

Reputation: 36860

If you insist on using SQLite then you don't have many good options. The most common suggestion is to have extra columns in your database, that are normalized values so if your plage column contains "Marée" then you also have a column plage_ascii that contains "maree"

you need to create the additional columns with migrations, then you would have a before_save action in your model...

before_save :create_normalized_strings

def create_normalized_strings
  self.handicap_ascii = handicap.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
  self.animaux_ascii = animaux.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
  # etc etc
end

Then in your search do...

if handicap
  test_handicap = handicap.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
  result = result.where('handicap_ascii LIKE ?', "%#{handicap}%")
end

It's not great, as it basically forces you to duplicate data in your database into extra columns. If you can consider more sophisticated databases other than SQLite then you'd be better off... personally I wouldn't ever use SQLite in a production environment.

Upvotes: 1

Related Questions