我有一个用户模型,它有两个角色:member
和admin
,默认为member
。此模型具有两个必需的属性payout_bank
和payout_account
,并且仅当角色为member
时才要求它们存在。
我的FactoryGirl用户有两个与角色相对应的特征。然后,我将两个必需的属性添加到member
特性中,但当我创建一个成员特性为"linting"且FactoryGirl处于打开状态的用户时,我会抱怨必需的属性未通过验证,因为它们是空白的。
如果我关闭linting,它将正确生成填写了payout_bank
和payout_account
的成员User。怎么回事?
模型用户.rb
class User < ActiveRecord::Base
validates_presence_of :payout_bank, :payout_account, if: :member?
def set_default_role
self.role ||= :member
end
end
工厂用户.rb
FactoryGirl.define do
factory :user do
sequence(:email) { |n| "user#{n}@email.com" }
password "password"
trait :member do
sequence(:email) { |n| "member#{n}@email.com" }
role "member"
payout_bank { Faker::Company.name }
payout_account { Faker::Number.number(10) }
end
trait :admin do
sequence(:email) { |n| "admin#{n}@email.com" }
role "admin"
status "active"
end
end
end
从工厂创建用户
FactoryGirl.lint
FactoryGirl.create(:member_user, :member)
输出
FactoryGirl::InvalidFactoryError: The following factories are invalid:
* member_user - Validation Failed: payout_bank cannot be blank, payout_account cannot be blank (ActiveRecord::RecordInvalid)/usr/local/lib/ruby/gems/2.3.0/gems/factory_girl-4.7.0/lib/factory_girl/linter.rb:12:in `lint!'
您必须在规范/模型目录中编写验证测试。有点像。
需要"rails_helper"需要"validates_email_format_of/rspec_matcher"
RSpec.describe BankAccount, type: :model do
it "should have a account number" do
bank_a = build(:bank_account, account_no: '')
expect(bank_a).to_not be_valid
end
end
我发现FactoryGirl.lint是导致验证失败的线路。这里的问题是linting将尝试创建没有特征的通用用户模型。由于我的用户模型默认为member
角色,并且该角色需要payout_bank
和payout_account
在场,因此验证失败。
解决方案是将这两个属性从member
特性移到工厂的基础中。
像这样的
FactoryGirl.define do
factory :user do
sequence(:email) { |n| "user#{n}@email.com" }
password "password"
payout_bank { Faker::Company.name } # Move here
payout_account { Faker::Number.number(10) } # Move here
trait :member do
sequence(:email) { |n| "member#{n}@email.com" }
role "member"
end
trait :admin do
sequence(:email) { |n| "admin#{n}@email.com" }
role "admin"
status "active"
payout_bank nil
payout_account nil
end
end
end