Factory Girl: How to set up a has_many/through association

后端 未结 4 1093
误落风尘
误落风尘 2020-12-30 20:57

I\'ve been struggling with setting up a has_many/through relationship using Factory Girl.

I have the following models:

class Job < Ac         


        
相关标签:
4条回答
  • 2020-12-30 21:14

    This worked for me

    FactoryGirl.define do
      factory :job do
    
        # ... Do whatever with the job attributes here
    
        factory :job_with_detail do
    
          # In later (as of this writing, unreleased) versions of FactoryGirl
          # you will need to use `transitive` instead of `ignore` here
          ignore do
            detail { create :detail }
          end
    
          after :create do |job, evaluator|
            job.details << evaluator.detail
            job.save
            job_detail = job.job_details.where(detail:evaluator.detail).first
    
            # ... do anything with the JobDetail here
    
            job_detail.save
          end
        end
      end
    end
    

    Then later

    # A Detail object is created automatically and associated with the new Job.
    FactoryGirl.create :job_with_detail
    
    # To supply a detail object to be associated with the new Job.
    FactoryGirl.create :job_with_detail detail:@detail
    
    0 讨论(0)
  • 2020-12-30 21:16

    You can solve this problem in the following way:

    FactoryBot.define do
      factory :job do
        # job attributes
    
        factory :job_with_details do
          transient do
            details_count 10 # default number
          end
    
          after(:create) do |job, evaluator|
            create_list(:details, evaluator.details_count, job: job)
          end
        end
      end
    end
    

    With this, you can create a job_with_details, that has options to specify how many details you want. You can read this interesting article for more details.

    0 讨论(0)
  • 2020-12-30 21:32

    Try something like this. You want to build a detail object and append it to the job's detail association. When you use after_create, the created job will be yielded to the block. So you can use FactoryGirl to create a detail object, and add it to that job's details directly.

    factory :job do
      ...
    
      after_create do |job|
        job.details << FactoryGirl.create(:detail)
      end
    end
    
    0 讨论(0)
  • 2020-12-30 21:32

    I faced this issue today and I found a solution. Hope this helps someone.

    FactoryGirl.define do
      factory :job do
    
        transient do
          details_count 5 # if details count is not given while creating job, 5 is taken as default count
        end
    
        factory :job_with_details do
          after(:create) do |job, evaluator|
            (0...evaluator.details_count).each do |i|
              job.details << FactoryGirl.create(:detail)
            end
          end
        end
      end  
    end
    

    This allows to create a job like this

    create(:job_with_details) #job created with 5 detail objects
    create(:job_with_details, details_count: 3) # job created with 3 detail objects
    
    0 讨论(0)
提交回复
热议问题