Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails MySQL ILIKE query

My syntax is off. I want to create a scope by_name that finds all agencies whose name attribute contains the passed in string (case insensitive).

Here is what I have:

class Agency < ActiveRecord::Base
  scope :by_name, ->(agency_name) { where('name ILIKE ?', "%#{agency_name}%") }
end

In the rails console I type in agencies = Agency.by_name("foo"). Here is the query generated:

SELECT `agencies`.* FROM `agencies`  WHERE (name ILIKE '%foo%')

Here is the error message:

Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ILIKE '%foo%')

like image 909
Neil Avatar asked Dec 01 '15 20:12

Neil


People also ask

Does Ilike work in MySQL?

It is in PostgreSQL the keyword ILIKE can be used instead of LIKE to make the match case-insensitive according to the active locale. This is not in the SQL standard but is a PostgreSQL extension. In MySQL you do not have ILIKE.

How do I make a case insensitive in MySQL?

select * from users where lower(first_name) = 'ajay'; The method is to make the field you are searching as uppercase or lowercase then also make the search string uppercase or lowercase as per the SQL function.

Is like in MySQL case sensitive?

Mysql ignores case for its LIKE comparisons.


2 Answers

I think it should be:

 scope :by_name, lambda { |agency_name| 
   where('name LIKE ?', "%#{agency_name}%") # not ILIKE
 }

It is in PostgreSQL the keyword ILIKE can be used instead of LIKE to make the match case-insensitive according to the active locale. This is not in the SQL standard but is a PostgreSQL extension.

In MySQL you do not have ILIKE. Checkout MySQL docs on string comparison functions.


Bonus - you can also use Arel. Take a look:

scope :by_name, lambda { |agency_name| 
  where(Agency.arel_table[:name].matches("%#{agency_name}%"))
}
like image 130
Andrey Deineko Avatar answered Sep 23 '22 08:09

Andrey Deineko


Why yes, because there's no such thing as ILIKE in MySQL. Only LIKE. You may have seen ILIKE as a case-insensitive version of LIKE in PostgreSQL, but your current RDBMS is different.

Your best bet is using LOWER on both sides to achieve mostly equivalent effect:

.where('LOWER(name) LIKE LOWER(?)', "%#{agency_name}%")

Credit to @mu is too short for his answer.

like image 41
D-side Avatar answered Sep 24 '22 08:09

D-side