Ruby on rails 3 Rails活动记录不区分大小写的查找

Ruby on rails 3 Rails活动记录不区分大小写的查找,ruby-on-rails-3,activerecord,find,Ruby On Rails 3,Activerecord,Find,虽然总的来说我喜欢数据库中的区分大小写,但有几次我觉得这很痛苦。用户名和电子邮件是我不想担心的字段的好例子——特别是在搜索时 在保存字符串之前,使用以下方法可以很容易地对字符串进行降级: 在你存钱之前 self.email.downcase! 结束 这样,用户名和电子邮件总是以小写形式保存。但是,通过用户名查找和通过电子邮件查找的最佳方式是什么?当然,我可以记得总是对传递到这些方法中的字符串进行降格,但这似乎并不十分枯燥 我曾想过,一旦我关闭了e-amail,我会覆盖find_by_email,

虽然总的来说我喜欢数据库中的区分大小写,但有几次我觉得这很痛苦。用户名和电子邮件是我不想担心的字段的好例子——特别是在搜索时

在保存字符串之前,使用以下方法可以很容易地对字符串进行降级:

在你存钱之前 self.email.downcase! 结束

这样,用户名和电子邮件总是以小写形式保存。但是,通过用户名查找和通过电子邮件查找的最佳方式是什么?当然,我可以记得总是对传递到这些方法中的字符串进行降格,但这似乎并不十分枯燥

我曾想过,一旦我关闭了e-amail,我会覆盖find_by_email,并用super打电话给原创者,但我没有幸运地发现这一点

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


PS我不认为像这样的相关文章()试图解决同样的问题。这里带有“lower”的自定义sql对我来说是无意义的,因为我已经确保所有这些值都是较低的——这是我现在需要下载的一个(可能来自用户输入的表单)。

其中一个应该很好:

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
更新

“按…查找…”。。。函数实际上是不存在的。当您调用其中一个方法时,ActiveRecord::Base会在
方法\u missing
方法中捕获您的调用,如果名称格式正确(包含列名等),则会为该类创建相应的find方法。在那之后,它将存在


如果您有一个
find\u by\u email
,默认情况下会调用它。如果它调用
super
,则意味着您尝试调用
ActiveRecord::Base.find\u by\u email
,但它不存在。
missing_方法
捕获它,并创建(实际上覆盖了您的)
find_by_email
实现。这就是为什么在那里叫超级不好。如果您使用自己的实现通过电子邮件进行查找,就像我在第二部分中所写的那样,那么它将工作得非常出色。

我做了如下操作:

def self.find_by_email(email)
  Member.find(:first, :conditions => ["lower(email) =?", email.downcase])
end
您可以讨论这是否正确,但一般来说,电子邮件应该规范化地进入数据库,以防止需要这样做

编辑: 轨道3:

Member.where("lower(email) =?", email.downcase).first

使用PostgreSQL,您可以执行以下操作:

User.where("email ILIKE ?", email).first

这对我有用!谢谢,但要低一点(:xxx)


包括(:responsibles)。where([“lower(name)| | | lower(contact)| | cnpj | | | | clients.rg | | rg ILIKE?”,“%#{params[:search]}%”)感谢Matzi,我喜欢你的建议,我将实施第一个建议。只是好奇,你会建议创建这个新方法而不是覆盖find_by_email吗?对我来说,重写它似乎更好,因为通过电子邮件调用find\u是很自然的,但我不确定如何实现。在rails 2.0中,它是有缺陷的,当您调用super时,缺少的\u方法重写了find\u by函数,导致它只工作了一次。我不知道它是否被纠正了,但安全总比抱歉好。如果你想通过电子邮件呼叫find_,那么使用我的第二个选项,无论如何都应该可以。对不起,没有按照你写的最后一部分“如果你想通过电子邮件呼叫find_,那么使用我的第二个选项…”。在您的第二个选项中,我不是仍然通过电子邮件调用find\u吗?我的意思是,我的函数的两个部分是两个不同的实现。如果调用函数find_by_email.awesome,则可以使用第二个函数。谢谢你的修改。我明白了。我将实施第二个解决方案。要么我没有抓住你的重点,要么你没有抓住我问题的重点。我同意,通常情况下,在储蓄之前,你应该先把情况弄清楚。如果您假设这样做了,您不需要“lower(email)=?”部分,但仍然需要email.downcase部分——因为电子邮件地址通常由用户提供,而他们可能没有downcase——这就是我的问题所在。我相信Matzi的回答是正确的。在插入DB时,您应该知道它是否被降级。Matzi的回答似乎是一个很好的解决方案,但它假设电子邮件在DB中是小写的,或者在传递到find_by_email方法时是小写的,我相信。His还将返回一系列电子邮件,而:first将返回作为实际成员对象的第一个响应。不?你说得很对:首先。不过,我不认为假设解决方案中的电子邮件已关闭是错误的,因为问题中特别指出了这一点。这是否容易受到SQL注入的攻击?请澄清(对于未来的读者),问题中的版本不会受到SQL注入的影响。评论中的版本不是。@Kevin什么的版本,Rails?PostgreSQL?@evanrmurphy我指的似乎是一条被删除的旧评论。
User.find_by'email ILIKE',email
是Rubocop建议的方式,使用而不是where.first