Factory Girl和嵌套属性验证错误

时间:2013-08-31 07:24:52

标签: ruby-on-rails validation factory-bot nested-attributes

我有一个模型公司,它接受Recruiters模型的嵌套属性。我需要在我的公司模型中验证在公司创建期间至少创建了一个招聘人员。

class Company < ActiveRecord::Base
    has_many :recruiters, dependent: :destroy, inverse_of: :company
    accepts_nested_attributes_for :recruiters, reject_if: ->(attributes) { attributes[:name].blank? || attributes[:email].blank? }, allow_destroy: true

    validate { check_recruiters_number } # this validates recruiters number

    private

    def recruiters_count_valid?
       recruiters.reject(&:marked_for_destruction?).count >= RECRUITERS_COUNT_MIN
    end

    def check_recruiters_number
       unless recruiters_count_valid?
           errors.add(:base, :recruiters_too_short, count: RECRUITERS_COUNT_MIN)
       end
    end
end

验证按预期工作但在添加此验证后我遇到FactoryGirl问题。我公司的工厂看起来像这样:

FactoryGirl.define do
   factory :company do
        association :industry
        association :user
        available_disclosures 15
        city 'Berlin'
        country 'Germany'

        ignore do
            recruiters_count 2
        end

        after(:build) do |company, evaluator|
            FactoryGirl.create_list(:recruiter, evaluator.recruiters_count, company: company)
        end

        before(:create) do |company, evaluator|
            FactoryGirl.create_list(:recruiter, evaluator.recruiters_count, company: company)
        end
    end 
end  

在测试中,当我做

company = create(:company)

我收到验证错误:

ActiveRecord::RecordInvalid:
   Validation failed: Company has to have at least one recruiter

当我第一次建立公司然后保存它时,测试通过:

company = build(:company)
company = save

当然,我不希望以这种方式改变我的所有测试以使它们工作。如何在创建公司模型期间设置工厂以创建关联模型?

2 个答案:

答案 0 :(得分:1)

您的validate { check_recruiters_number }不合理。删除它。

为什么呢?您需要拥有有效的公司ID才能节省招聘人员,但您的验证人员会因为没有招聘人员而阻止公司有效。这是矛盾的。

答案 1 :(得分:0)

这是一个老问题,但我有类似的问题,我用以下代码解决了它(为了符合你的情况而重写):

FactoryGirl.define do
   factory :company do
        association :industry
        association :user
        available_disclosures 15
        city 'Berlin'
        country 'Germany'

        ignore do
            recruiters_count 2
        end

        after(:build) do |company, evaluator|
            company.recruiters = FactoryGirl.build_list(:recruiter, evaluator.recruiters_count, company: company)
        end
    end 
end