虽然我在数据库中总体上喜欢区分大小写,但有几次我觉得很痛苦。 user_name和email是很好的例子,我不想担心这个案例 - 特别是在搜索时。
在使用以下内容保存之前,可以很容易地对字符串进行缩写:
before_save do self.email.downcase! 端
这样,user_name和电子邮件始终以小写形式保存。但是find_by_user_name和find_by_email的最佳方法是什么?我当然可以记得总是把我传递给那些方法的字符串放在一边 - 但这看起来并不是很干。
我曾经考虑过覆盖find_by_email,并且在我用电子邮件发送电子邮件之后用超级电话调用原件,但我没有任何运气可以解决这个问题。
那么,最好的方法是什么?
PS我不认为像这样的相关帖子(how can I write a case-insensitive find_by_email for Rails 3)正试图解决同样的问题。自定义sql在这里" lower"对我来说是无用的,因为我已经确保所有这些值都更低 - 它是现在进入的(可能来自用户输入它的形式),我需要降级。
答案 0 :(得分:32)
使用PostgreSQL,您可以:
User.where("email ILIKE ?", email).first
答案 1 :(得分:18)
其中一个应该是好的:
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
实现。这就是为什么在那里打电话不好的原因。如果您使用自己的实现来通过电子邮件进行查找,就像我在第二部分中所写的那样,那么它将会非常出色地工作。
答案 2 :(得分:10)
我做了类似的事情:
def self.find_by_email(email)
Member.find(:first, :conditions => ["lower(email) =?", email.downcase])
end
您可以讨论这是否正确,但通常情况下,电子邮件应该被规范化进入数据库,以防止需要这样做。
编辑: Rails 3:
Member.where("lower(email) =?", email.downcase).first
答案 3 :(得分:0)
它对我有用!谢谢你,但是用较低的(:xxx)。
Client.includes(:responsibles).where([“lower(name)|| lower(contact)|| cnpj || clients.rg || rg ILIKE?”,“%#{params [:search]} %“])