web-dev-qa-db-ja.com

Rails postgresqlで大文字と小文字を区別しない順序で行う方法

開発環境をsqlite3からpostgresql 8.4に切り替える途中で、もう1つハードルがあります。

私のオリジナルでは、ヘルパーメソッドに次の行がありました。

result = Users.find(:all, :order => "name collate NOCASE")

大文字と小文字を区別しない非常に優れた検索を提供します。これをpostgresqlに複製することはできません。簡単なはずです-アイデアはありますか?

ありがとう。

52
brad
result = Users.find(:all, :order => "LOWER(name)")

ブラッドとフランクの両方から少し取る。

80
LanceH

LanecHの回答 Rails 3+(Rails 4 and 5を含む)に適合:

users = User.order('LOWER(name)')

または、再利用できる名前付きスコープを作成します。

class User < ActiveRecord::Base
  scope :order_by_name, -> { order('LOWER(name)') }
end

users = User.order_by_name
24
Thomas Klemm

Rails 5.2では、受け入れられた回答を使用すると警告が表示されるでしょう。

DEPRECATION WARNING:危険なクエリメソッド(生のSQLとして引数が使用されるメソッド)が非属性引数で呼び出されました: "LOWER(?)ASC"。

別の方法としては、Arelを使用することもできます(現在はRailsに統合されています)。

results = User.order(User.arel_table['name'].lower.asc)
# results.to_sql == "SELECT \"users\".* FROM \"users\" ORDER BY LOWER(\"users\".\"name\") ASC" 
19
Mario Pérez

列を citext タイプとして保存することを検討しましたか?私が理解しているように、lower()への呼び出しを実際に内部化するだけです。その後は自動的に行われます。大文字と小文字を区別する検索が必要な場合は、これが最善の方法とは限りません。

6
rfusca

SQLでは、ORDER BY LOWER(columnname)を使用できますが、Rubyでそれを行う方法はわかりません。関数インデックス(LOWER(columnname)にもあります)は、高速化に役立ちます。

5
Frank Heikens