Rails 3到4迁移唯一性验证问题

fbe*_*ger 8 ruby validation rspec ruby-on-rails

上下文

我们正在从Rails 3.2.12迁移到4.0.2,从Ruby 1.9.3迁移到2.1.8.

我们有很多测试覆盖率来完成RSpec形式的迁移.

问题

检查卡模型上的唯一性验证失败的规范之一.

validates :mobile, uniqueness: {scope: :program_member_id, message: I18n.t('models.card.error.cardholder_already_has_mobile')}, if: :mobile
Run Code Online (Sandbox Code Playgroud)

哪一个program_member可能只有一张mobile: true卡.

该规范为该成员创建了2张牌,将一张牌变为移动牌,然后在使用第二张牌时预期验证的消息.

let(:program) { FactoryGirl.create(:program) }
let(:card) { FactoryGirl.create(:card, program: program) }

context 'when cardholder already has a mobile card' do
  it 'fails validation' do
    card2 = FactoryGirl.create(:card, program: program)
    program_member_user = FactoryGirl.create(:program_member_user, card_number: card2.cardnumber)
    program_member = program_member_user.program_members.first

    program_member.cards << card2
    card2.update_attributes(:mobile => true)

    program_member.cards << card
    card.update_attributes(:mobile => true)

    expect(card.errors.messages).to include(:mobile=>[I18n.t('models.card.error.cardholder_already_has_mobile')])
  end
end
Run Code Online (Sandbox Code Playgroud)

期望:

expected {} to include {:mobile=>["Cardholder already has a mobile card"]}
Run Code Online (Sandbox Code Playgroud)

当我去我们的master分支时,这个规范通过.

从此规范工作到失败的唯一因素是Rails 3到4迁移.

试图在控制台中运行规范代码只是为了找到该成员有2个移动卡并为两个实例做card.valid?返回true.

Rails 4中的唯一性验证或验证生命周期有什么变化吗?

fbe*_*ger 1

好吧,我正在做某事。

\n\n

我使用相同的 Ruby 和 Rails 版本创建了一个测试项目。

\n\n

https://github.com/frank184/test_uniquness

\n\n

在这个项目中,我将有一个User模型,其中有一admin列作为布尔值,并具有类似的验证。

\n\n
validates_uniqueness_of :admin, if: :admin?\n
Run Code Online (Sandbox Code Playgroud)\n\n

我使用 shoulda-matchers 和 rspec 来描述期望的结果。

\n\n
require \'rails_helper\'\n\nRSpec.describe User, type: :model do\n  let(:user) { build :user }\n  subject { user }\n\n  describe \'validations\' do\n    context \'when admin = true\' do\n      before(:each) { user.admin = true }\n      it { is_expected.to validate_uniqueness_of(:admin)  }\n    end\n  end\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

规范失败,输出如下:

\n\n
Failures:\n\n  1) User validations when admin = true should validate that :admin is case-sensitively unique\n     Failure/Error: it { is_expected.to validate_uniqueness_of(:admin)  }\n\n       User did not properly validate that :admin is case-sensitively unique.\n         After taking the given User, whose :admin is \xe2\x80\xb9true\xe2\x80\xba, and saving it as\n         the existing record, then making a new User and setting its :admin to\n         \xe2\x80\xb9true\xe2\x80\xba as well, the matcher expected the new User to be invalid, but\n         it was valid instead.\n     # ./spec/models/user_spec.rb:10:in `block (4 levels) in <top (required)>\'\n\nFinished in 0.11435 seconds (files took 0.79997 seconds to load)\n1 example, 1 failure\n
Run Code Online (Sandbox Code Playgroud)\n\n

我认为代码很好,并将 Rails 准确地升级到 4.1.0。

\n\n

规范通过了!

\n\n
bundle update\nrspec\n.\n\nFinished in 0.09538 seconds (files took 1.28 seconds to load)\n1 example, 0 failures\n
Run Code Online (Sandbox Code Playgroud)\n