10

虽然总的来说我喜欢在我的数据库中区分大小写,但有几次我觉得它很痛苦。user_name 和 email 是我不想担心的字段的好例子——尤其是在搜索时。

在保存之前使用以下内容很容易将字符串小写:

before_save 做 self.email.downcase!结尾

这样,用户名和电子邮件始终以小写形式保存。但是 find_by_user_name 和 find_by_email 的最佳方法是什么?我当然可以记住总是将我传递给这些方法的字符串小写——但这似乎不是很干。

一旦我缩小电子邮件的大小写,我就考虑过覆盖 find_by_email 并用 super 调用原始文件,但我没有运气弄清楚这一点。

那么,最好的方法是什么?

PS 我不认为像这样的相关帖子(如何为 Rails 3 编写不区分大小写的 find_by_email)试图解决同样的问题。此处带有“较低”的自定义 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_... 函数实际上是不存在的。当您调用其中之一时,ActiveRecord::Base 会在method_missing方法中捕获您的调用,并且如果名称格式正确(包含列名等),则会为该类创建适当的 find 方法。之后它就会存在。

如果您有find_by_email,默认情况下会调用它。如果它调用super,则意味着您尝试调用ActiveRecord::Base.find_by_email,它不存在。missing_method捕获它,并创建(实际上覆盖您的)实现find_by_email。这就是为什么在那里称呼 super 不好。如果您使用自己的实现来通过电子邮件查找,就像我在第二部分中所写的那样,那么它将非常有效。

于 2012-07-05T09:48:17.503 回答
12

我做了这样的事情:

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

您可以就这是否正确进行辩论,但通常应该将电子邮件规范化到数据库中以防止需要这样做。

编辑:Rails 3:

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

这个对我有用!谢谢,但使用较低(:xxx)。

Client.includes(:responsibles).where(["lower(name) || lower(contact) || cnpj || clients.rg || rg ILIKE ?", "%#{params[:search]}%"] )

于 2016-12-20T12:23:58.760 回答