web-dev-qa-db-ja.com

Rails MySQL ILIKEクエリ

私の構文はオフです。名前属性に渡された文字列が含まれるすべてのagenciesを検索するスコープ_by_name_を作成したい(大文字と小文字は区別されません)。

これが私が持っているものです:

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

Railsコンソールでagencies = Agency.by_name("foo")と入力します。生成されたクエリは次のとおりです。

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

エラーメッセージは次のとおりです。

Mysql2 :: Error:SQL構文にエラーがあります。 MySQLサーバーのバージョンに対応するマニュアルで、 'ILIKE'%foo% 'の近くで使用する正しい構文を確認してください)

11
Neil

私はそれがそうあるべきだと思います:

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

PostgreSQLにあります LIKEの代わりにキーワードILIKEを使用して、アクティブなロケールに応じて大文字と小文字を区別せずに一致させることができます。これはSQL標準にはありませんが、PostgreSQLの拡張機能です。

MySQLでは、ILIKEはありません。チェックアウト 文字列比較関数のMySQLドキュメント


ボーナス- Arel も使用できます。見てください:

scope :by_name, lambda { |agency_name| 
  where(Agency.arel_table[:name].matches("%#{agency_name}%"))
}
18
Andrey Deineko

MySQLにはILIKEのようなものはありません なので、なぜそうなのか。 LIKEのみ。 PostgreSQLでは、ILIKELIKEの大文字と小文字を区別しないバージョンと見なしていたかもしれませんが、現在のRDBMSは異なります。

あなたの最善の策は、両側でLOWERを使用して、ほぼ同等の効果を達成することです:

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

@ muは短すぎる の功績 answer .

8
D-side