简体   繁体   English

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

[英]Rails 3 to 4 migration uniqueness validation issues

Context 语境

We are migrating from Rails 3.2.12 to 4.0.2 and Ruby 1.9.3 to 2.1.8. 我们正在从Rails 3.2.12迁移到4.0.2,从Ruby 1.9.3迁移到2.1.8。

We have a lot of test coverage to accomplish the migration in the form of RSpec. 我们有大量的测试内容可以以RSpec的形式完成迁移。

Issue 问题

One of the spec that checks that a uniqueness validation on a Card model is failing. 检查Card模型上的唯一性验证失败的规范之一。

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

Where a program_member may only have one mobile: true card. 如果program_member只能拥有一个mobile: true卡。

The spec creates 2 cards for the member, turns one into a mobile card, then expects the validation's message when doing so with the second card. 规范会为该会员创建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

Expectation: 期望:

expected {} to include {:mobile=>["Cardholder already has a mobile card"]}

When I go to our master branch, this spec passes. 当我转到master分支时,此规范通过。

The only factor that has changed from this spec working to failing is the Rails 3 to 4 migration. 从此规范更改为失败的唯一因素是Rails 3到4的迁移。

Tried running the spec code in console only to find the member has 2 mobile cards and doing card.valid? 试图在控制台中运行规范代码,只是发现该成员有2张移动卡并且正在执行card.valid? returns true for both instances. 对于两个实例均返回true

Question

Has anything changed in Rails 4 in regards to uniqueness validation or validation life cycle? 在Rails 4中,关于唯一性验证或验证生命周期有什么变化吗?

Alright so I'm onto something. 好吧,所以我很着迷。

I created a test project using the same Ruby and Rails version. 我使用相同的Ruby和Rails版本创建了一个测试项目。

https://github.com/frank184/test_uniquness https://github.com/frank184/test_uniquness

In this project, I would have a User model that has an admin column as a boolean with a similar validation. 在这个项目中,我将有一个User模型,其中的admin列为具有类似验证的布尔值。

validates_uniqueness_of :admin, if: :admin?

I used shoulda-matchers and rspec to describe the desired outcome. 我使用了Shoulda-matchers和rspec来描述所需的结果。

require 'rails_helper'

RSpec.describe User, type: :model do
  let(:user) { build :user }
  subject { user }

  describe 'validations' do
    context 'when admin = true' do
      before(:each) { user.admin = true }
      it { is_expected.to validate_uniqueness_of(:admin)  }
    end
  end
end

The spec failed with the following output: 规格失败,并显示以下输出:

Failures:

  1) User validations when admin = true should validate that :admin is case-sensitively unique
     Failure/Error: it { is_expected.to validate_uniqueness_of(:admin)  }

       User did not properly validate that :admin is case-sensitively unique.
         After taking the given User, whose :admin is ‹true›, and saving it as
         the existing record, then making a new User and setting its :admin to
         ‹true› as well, the matcher expected the new User to be invalid, but
         it was valid instead.
     # ./spec/models/user_spec.rb:10:in `block (4 levels) in <top (required)>'

Finished in 0.11435 seconds (files took 0.79997 seconds to load)
1 example, 1 failure

I decided that the code was good and bumped Rails to 4.1.0 exactly. 我认为代码不错,并将Rails准确地提高到了4.1.0。

The spec passed! 规格通过了!

bundle update
rspec
.

Finished in 0.09538 seconds (files took 1.28 seconds to load)
1 example, 0 failures

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM