加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Railstutorial.org验证唯一的电子邮件

发布时间:2020-12-17 02:30:48 所属栏目:百科 来源:网络整理
导读:在 Ruby on Rails 3教程的6.2.4节中,Michael Hartl描述了一个关于检查电子邮件地址唯一性的警告:如果两个相同的请求及时接近,请求A可以通过验证,然后B通过验证,然后A得到保存,然后B得到保存,你得到两个具有相同值的记录.每个都在检查时有效. 我的问题不在于
在 Ruby on Rails 3教程的6.2.4节中,Michael Hartl描述了一个关于检查电子邮件地址唯一性的警告:如果两个相同的请求及时接近,请求A可以通过验证,然后B通过验证,然后A得到保存,然后B得到保存,你得到两个具有相同值的记录.每个都在检查时有效.

我的问题不在于解决方案(对数据库设置了一个独特的约束,因此B的保存不起作用).这是关于编写测试以证明解决方案有效.我尝试自己编写,但无论我想出什么,只能模仿常规的,简单的唯一性测试.

作为rspec的全新,我的天真方法是编写场景:

it 'should reject duplicate email addresses with caveat' do
  A = User.new( @attr ) 
  A.should be_valid          # always valid

  B = User.new( @attr )
  B.should be_valid          # always valid,as expected

  A.save.should == true      # save always works fine

  B.save.should == false     # this is the problem case
  # B.should_not be_valid    # ...same results as "save.should"
end

但是这个测试在与常规唯一性测试完全相同的情况下通过/失败;编写代码时,B.save.should == false会传递,以便常规测试失败时常规唯一性测试通过并失败.

所以我的问题是“如何编写一个可以验证我正在解决这个问题的rspec测试?”如果答案结果是“它很复杂”,那么我应该看一下不同的Rails测试框架吗?

解决方法

情况很复杂.竞争条件非常糟糕,因为它们很难再现.在内部,保存就是这样的:

>验证.
>写入数据库.

因此,要重现计时问题,您需要安排两个保存调用重叠,如下所示(伪Rails):

a.validate    # first half of a.save
b.validate    # first half of b.save
a.write_to_db # second half of a.save
b.write_to_db # second half of b.save

但是你不能打开保存方法并且非常容易地摆弄它的内部结构.

但是(这是一个很大但是),you can skip the validations entirely:

Note that save also has the ability to skip validations if passed :validate => false as argument. This technique should be used with caution.

所以,如果你使用

b.save(:validate => false)

你应该只获得“写入数据库”b的一半保存并将数据发送到数据库而无需验证.这应该会触发数据库中的约束违规,我很确定会引发ActiveRecord::StatementInvalid异常,所以我认为你需要查找异常,而不仅仅是从save中返回错误:

b.save(:validate => false).should raise_exception(ActiveRecord::StatementInvalid)

您可以将其收紧,以查找特定的异常消息.我没有任何方便测试此测试,因此请在Rails控制台中尝试并适当调整您的规范.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读