【问题标题】:Why is Rails query case sensitive in production but not development?为什么 Rails 查询在生产中区分大小写而不是开发?
【发布时间】:2017-02-09 00:22:35
【问题描述】:

我今天在调试 Rails 5.0.1 应用时,发现了以下意外问题。我在数据库中有一个用户,他的电子邮件地址为Thomas.A.Jones@company.foo。当我跑步时

User.find_by(email: "thomas.a.jones@company.foo")

在生产中,我收到了 nil 回复。但是,如果我执行

User.find_by(email: "Thomas.A.Jones@company.foo")

它成功找到了记录。奇怪的是,当 Rails 应用程序在开发模式下运行时,这不会发生。我可以用thomas.a.jones@company.fooThomas.A.Jones@company.foo查询,总能找到记录。

什么可能导致 Rails 在生产环境中进行区分大小写的搜索?数据库是 Postgres。所有这些都在同一台机器上用相同的代码进行测试。

2017 年 2 月 10 日更新

不幸的是,重建我的开发环境后问题就消失了。在阅读了下面的一些 cmets 之后,生产中区分大小写的搜索是 Postgres/Rails 的预期行为。目前尚不清楚为什么我的开发环境(在同一台机器上)执行不区分大小写的搜索。如果我发现更多信息,我会更新......

【问题讨论】:

  • 你的后端数据库是什么?即使正在运行完全相同的查询,也可能存在版本差异,或者由于服务器默认设置而导致架构差异。例如,with MySQL it depends on collation。将您的开发表架构与您的生产架构进行比较并寻找差异。
  • 在这种特殊情况下,一切都应该是一样的。它是同一台计算机,相同的后端数据库(Postgres)。我通过运行所有迁移在开发模式下重新生成了整个数据库。然后我通过重新运行所有迁移重新创建了生产数据库。但是,点了。我会看看我是否能发现两者之间决赛桌/模式的区别。
  • 我只是在这里提出建议,而不是下结论。这很可能是一个微妙的整理问题。您是否尝试过工作数据库的 pg_restore 以查看发生了什么变化?

标签: ruby-on-rails ruby postgresql


【解决方案1】:

Postgres 默认区分大小写。您可以使用ILIKE 来避免区分大小写。

根据活动区域设置,可以使用关键字 ILIKE 代替 LIKE 使匹配不区分大小写。这不在 SQL 标准中,而是 PostgreSQL 扩展。

或将两者都改为小写然后搜索:

User.where("LOWER(email) = ?", email.downcase)

【讨论】:

  • 感谢您提供的信息。我希望避免使用 ILIKE 或 LOWER。希望我能找出为什么这两个环境的行为不同......这让我很害怕。
【解决方案2】:

我不确定,为什么会这样。但是有一个简单的解决方案。

将此放入模型中。

例如:user.rb

class User < ActiveRecord::Base
  before_save { self.email = email.downcase }
end

【讨论】:

    猜你喜欢
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 2021-12-06
    相关资源
    最近更新 更多