Rails MySQL ILIKE查询

Nei*_*eil 10 ruby mysql activerecord ruby-on-rails

我的语法已关闭.我想创建一个范围by_name,查找所有agencies其name属性包含传入的字符串(不区分大小写).

这是我有的:

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

在rails控制台中输入agencies = Agency.by_name("foo").这是生成的查询:

SELECT `agencies`.* FROM `agencies`  WHERE (name ILIKE '%foo%')
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

Mysql2 ::错误:您的SQL语法有错误; 查看与您的MySQL服务器版本对应的手册,以便在'ILIKE'%foo%'附近使用正确的语法

And*_*eko 17

我认为它应该是:

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

在PostgreSQL中,可以使用关键字ILIKE而不是LIKE来根据活动区域设置使匹配不区分大小写.这不是SQL标准,而是PostgreSQL扩展.

在MySQL中你没有ILIKE.在字符串比较函数上查看MySQL文档.


奖金 - 您也可以使用Arel.看一看:

scope :by_name, lambda { |agency_name| 
  where(Agency.arel_table[:name].matches("%#{agency_name}%"))
}
Run Code Online (Sandbox Code Playgroud)


D-s*_*ide 7

为什么是,因为在MySQL中没有这样的东西ILIKE.只有LIKE.你可能已经看到PostgreSQL中的ILIKE一个不区分大小写的版本LIKE,但你当前的RDBMS是不同的.

你最好的选择是LOWER双方使用以达到大致相同的效果:

.where('LOWER(name) LIKE LOWER(?)', "%#{agency_name}%")
Run Code Online (Sandbox Code Playgroud)

感谢@mu太短了他的答案.

  • 这不是一个理想的解决方案,因为如果 name 列上存在索引,则这将不允许查询优化器使用索引,更好的解决方案是将表的排序规则设置为 utf8_general_ci - ci 表示不区分大小写,这样做将使所有文本匹配不区分大小写 (2认同)