Rails Active Record不区分大小写查找

时间:2012-07-05 09:37:48

标签: ruby-on-rails-3 activerecord find

虽然我在数据库中总体上喜欢区分大小写,但有几次我觉得很痛苦。 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"对我来说是无用的,因为我已经确保所有这些值都更低 - 它是现在进入的(可能来自用户输入它的形式),我需要降级。

4 个答案:

答案 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_emailmissing_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]} %“])