【问题标题】:Problem with validates_uniqueness_ofvalidates_uniqueness_of 的问题
【发布时间】:2011-01-19 10:53:00
【问题描述】:

我在我们的网站上使用 rails 2.3.5 和 Authlogic,我在数据库中遇到错误,因为用户的 hoptoad 试图保存重复的电子邮件。问题是,很明显我的模型上有validates_uniqueness_of :email

在我的开发测试中,我得到了预期的验证错误,并且用户没有被保存,但在生产中,我不断在数据库层收到这个错误。

我已经对区分大小写的电子邮件进行了测试,并且它也得到了正确验证。

我已经检查了类并且没有 attr_accessor 或任何其他属性覆盖,我不认为 Authlogic 会以错误的方式做到这一点......

生产中会发生什么?是否存在 Rails 验证不起作用的情况?

【问题讨论】:

    标签: ruby-on-rails validation authlogic


    【解决方案1】:

    在您的开发日志中找到运行validates_uniqueness_of 的SQL,如果您看到类似WHERE (email = BINARY 'foo@example.com') 的内容,请尝试使用FOO@EXAMPLE.COM 创建用户,现在您可以重现DB 级重复异常。

    要解决此问题,请将以下代码放入config/initializers/patches.rb

    class ActiveRecord::ConnectionAdapters::Mysql2Adapter
      def case_sensitive_equality_operator
        "="
      end
    end
    

    请注意,如果您使用的是 Rails 2,Mysql2Adapter 应该是 MysqlAdapter

    附带说明,这是 Rails IMO 中长期存在的错误 - 在 Ruby 级别处理区分大小写根本没有意义。如果您需要区分大小写的查找,您应该有utf8_bin 的列排序规则。如果您需要不区分大小写的查找,您应该有utf8_general_ci 的列排序规则。在 where 子句中应用 BINARY 函数将禁用索引,而 validates_uniqueness_of 会在您每次尝试创建/更新记录时进行全表扫描。如果你有数百万条记录,那你就完蛋了。上面的补丁也将解决这个问题 - 事实上,这是我创建该补丁的最初动机。

    如果您同意,请 +1 到https://github.com/rails/rails/issues/1399 :)

    【讨论】:

      【解决方案2】:

      您是否尝试过重新创建场景。为什么要抛出保证 Hoptoad 通知的错误。我的意思是,基本上如果你有一个它不应该保存用户,也不应该抛出错误让 hoptoad 通知你。

      同样使用 authlogic,我认为您不需要为电子邮件指定 validate_uniqueness_of。通常 authlogic 会为您解决这个问题。

      所以我想,是时候深入了解一下了。

      查看日志,并尝试在本地重新创建此错误。追溯导致错误的步骤总是最好的。

      更多细节、错误堆栈、代码肯定会有所帮助。

      【讨论】:

      • 是的,我知道当电子邮件已经存在时,hoptoad 不应该抛出错误。它应该简单地验证并返回带有消息“此电子邮件已在使用中”的表单。这种行为几乎在所有情况下都会发生,但在少数情况下,rails 正在验证已经存在的电子邮件,因此它会尝试保存用户,并且由于 UNIQUE 索引,数据库会抛出错误。我正在尝试重新创建它,但即使使用相同的数据,我也会得到正确的行为而不是错误:/
      【解决方案3】:

      只是一个猜测,但可能是您的电子邮件列允许为空,validates_uniqueness_of 忽略了 nil(或空白)值,并且您的用户试图在未指定其电子邮件地址的情况下进行注册?

      【讨论】:

      • 不,错误总是与正在传递但已经在数据库中的电子邮件有关。我还验证了电子邮件的存在,所以我认为 rails 不会同时在 2 次验证中失败
      • 这个想法就这么多了。我建议更改您的生产应用程序的错误日志记录级别,以便显示它正在运行的查询。我想这也可能是区分大小写的问题,或者可能与尾随空格有关?
      猜你喜欢
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      • 1970-01-01
      • 2015-10-15
      • 1970-01-01
      相关资源
      最近更新 更多