【问题标题】:Ruby on Rails ActiveRecord uniqueness validationRuby on Rails ActiveRecord 唯一性验证
【发布时间】:2013-02-03 06:08:29
【问题描述】:

我对 Rails 很陌生,正在阅读有关该主题的一些资源。我有一些问题。好的,假设我们确实有一个模型,可以验证某些属性的唯一性:

class User < ActiveRecord::Base
  attr_accesible :name
  validates :name, uniqueness: true
end

所以,我现在有理由预期,我将无法在数据库中创建(或更准确地说——保存)两个具有相同名称的 User 实例。但是,该资源确实坚持认为它仍然是可能的!

  • 部分用户登录。
  • 多次点击“登录”按钮
  • 请求 1 在内存中创建用户(有效)
  • 请求 2 在内存中创建用户(有效)
  • 请求 1 已成功保存
  • 请求 2 已成功保存

后来此消息来源建议将数据库中的索引添加到“名称”列并使其唯一。

但是,如果正如我之前所说的那样——在保存过程中进行验证,那么如何保存第二个请求?还是我丢失了什么?

(我提到的资源是Rails Tutorial

【问题讨论】:

  • 这只发生在大型系统中。当流量很高时,第一个请求的响应将被延迟。所以第二个请求模型验证将通过。两者都将保存在数据库中。而且你不能在本地机器上生产它。我的意思是在开发模式下。如果你想实际看到它,你的应用程序应该有很高的流量。当您扩展应用程序以在不同的盒子上获取请求时也会发生这种情况(我的意思是负载平衡)。当用户双击请求可能会转到不同的节点。两者都将同时通过验证并保存在数据库中。
  • 或者您可以在验证期间或 before_save 期间将其置于睡眠状态,以查看结果。 :)
  • 嗯,但是交易呢?如果我说对了,问题在于数据库本身很长时间没有响应,并且可以发出另一个同名的请求?但我认为这是不可能的,直到第一个请求完成。

标签: ruby-on-rails validation rails-activerecord


【解决方案1】:

第二个请求在第一条记录保存到 DB 之前被触发,因此 rails 验证没有指定名称的记录并允许它保存。这就是为什么建议向数据库字段添加唯一性,以避免这些边缘情况。

或者换句话说,记录通过了内存中的验证。

【讨论】:

  • 嗯,那我还是不明白。我“启动”了我的 rails 控制台,创建了两个具有 same 名称的用户,这没关系,直到我在第一个上调用 save 为止。然后我重复操作,创建了 3 个用户,一个已经在 db 上,两个在内存中。它仍然没问题。所以,我想说的是——验证不是在内存中发生,而是在保存到数据库时发生。
  • 试试这个:u = User.create(name: "test") 和他们u2 = User.new(name: "test"),他们u2.valid? 应该是假的。
  • 是的,确实如此。所以,作为我的问题的解决方案,我看到:当第一个用户被创建和第二个用户 - 在数据库中不是这样的记录,那么有效吗? (实际上从 DB 调用 SELECT bla-bla)对两者都是正确的。之后我保存user1,然后保存user2。但是,有效吗?对于 user2 再次返回 true,因为重载数据库的高延迟,无法正确服务 user2.valid? (及时)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-04
  • 2018-06-24
  • 2010-10-29
  • 2010-10-14
相关资源
最近更新 更多