10

一般的に、私は自分のデータベースで大文字と小文字を区別するのが好きですが、それが面倒だと感じることが数回あります。user_name と email は、特に検索時に大文字と小文字を区別したくないフィールドの良い例です。

次のようなものを使用して、保存する前に文字列を簡単にダウンケースできます。

before_save do self.email.downcase! 終わり

このようにして、user_name とメールは常に小文字で保存されます。しかし、find_by_user_name と find_by_email の最良の方法は何ですか? もちろん、これらのメソッドに渡す文字列を常に小文字にすることを忘れないでください。しかし、それはあまり DRY ではないようです。

私は find_by_email をオーバーライドし、電子メールを小文字化したら super でオリジナルを呼び出すことを考えましたが、それを理解する運がありませんでした。

それで、これを行う最善の方法は何ですか?

PS私は、このような関連記事(Rails 3の大文字と小文字を区別しないfind_by_emailを書くにはどうすればよいか)が同じ問題を解決しようとしているとは思わない。ここで「lower」を使用したカスタムSQLは、これらの値がすべて低いことをすでに確認しているため、私にとっては無意味です。これは、現在入力されているものであり(おそらくユーザーが入力したフォームから)、小文字にする必要があります。

4

4 に答える 4

34

PostgreSQL を使用すると、次のことができます。

User.where("email ILIKE ?", email).first
于 2013-02-18T16:09:10.073 に答える
19

これらのいずれかが適切である必要があります。

def self.find_by_lower_email(email)
  User.find_by_email(email.downcase)
end
# OR
def self.find_by_email(email)
  User.find(:all, :conditions => ["email = lower(?)", email]) 
end

更新

find_by_... 関数は実際には存在しないものです。それらの 1 つを呼び出すと、ActiveRecord::Base がその呼び出しをmethod_missingメソッドでキャッチし、名前が適切にフォーマットされている (列名などを含む) 場合、そのクラスに適切な find メソッドが作成されます。その後、それは存在します。

がある場合は、find_by_emailデフォルトで呼び出されます。を呼び出す場合は、存在しないsuperを呼び出そうとしていることを意味します。ActiveRecord::Base.find_by_emailはそれmissing_methodをキャッチし、実装を作成します (実際には上書きします) find_by_email。そのため、そこにスーパーを呼び出すのは良くありません。第二部で書いたように、メールで検索するための独自の実装を使用すると、見事に機能します。

于 2012-07-05T09:48:17.503 に答える
12

私はこのようなことをしました:

def self.find_by_email(email)
  Member.find(:first, :conditions => ["lower(email) =?", email.downcase])
end

これが正しいかどうかについて議論することはできますが、一般的に、これを行う必要がないように、電子メールはデータベースに入るのを正規化する必要があります。

編集:レール3:

Member.where("lower(email) =?", email.downcase).first
于 2012-08-15T18:41:58.463 に答える