Rails Active Record不区分大小写查找

sno*_*guy 9 activerecord find ruby-on-rails-3

虽然我在数据库中总体上喜欢区分大小写,但有几次我觉得很痛苦.user_name和email是我不想担心的字段的好例子 - 特别是在搜索时.

在使用以下内容保存之前,可以轻松地将字符串置为字符串:

before_save做self.email.downcase!结束

这样,user_name和电子邮件始终以小写形式保存.但是find_by_user_name和find_by_email的最佳方法是什么?我当然可以记得总是将我传递给那些方法的字符串 - 但这看起来不是很干.

我曾经考虑过覆盖find_by_email,并且在我降低电子邮件的情况下用super调用原始版本,但我没有任何运气可以搞清楚.

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

PS我不认为像这样的相关帖子(如何为Rails 3编写不区分大小写的find_by_email)正试图解决同样的问题.这里带有"lower"的自定义sql对我来说是无用的,因为我已经确保所有这些值都更低 - 它是现在进入的(可能来自用户输入它的表单),我需要下载.

tom*_*bak 32

使用PostgreSQL,您可以:

User.where("email ILIKE ?", email).first
Run Code Online (Sandbox Code Playgroud)

  • 为了清楚(对于未来的读者),问题中的版本是安全的SQL注入.评论中的版本不是. (5认同)
  • `User.find_by 'email ILIKE ?', email` 是 Rubocop 推荐的方式,使用 [`find_by`](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find_by) 代替从哪里开始。 (2认同)

Mat*_*tzi 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
Run Code Online (Sandbox Code Playgroud)

更新:

find_by _...函数实际上是不存在的函数.当您调用其中一个时,ActiveRecord :: Base会捕获您在method_missing方法中的调用,如果名称格式正确(包含列名等),则会为该类创建相应的find方法.之后它将存在.

如果你有find_by_email,它将默认调用.如果它调用super,则意味着您尝试调用ActiveRecord::Base.find_by_email,这不存在.在missing_method捕获它,并创建(实际上将覆盖)find_by_email的实现.这就是为什么在那里打电话不好的原因.如果您使用自己的实现来通过电子邮件进行查找,就像我在第二部分中所写的那样,那么它将会非常出色地工作.


ryl*_*anb 10

我做了这样的事情:

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

你可以讨论这是否正确,但通常电子邮件应该被规范化进入数据库,以防止需要这样做.

编辑:Rails 3:

Member.where("lower(email) =?", email.downcase).first
Run Code Online (Sandbox Code Playgroud)