繁体   English   中英

Factory Girl:如何建立has_many/through关联

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

我一直在努力使用 Factory Girl 建立has_many/through关系。

我有以下型号:

class Job < ActiveRecord::Base
  has_many :job_details, :dependent => :destroy
  has_many :details, :through => :job_details
end

class Detail < ActiveRecord::Base
  has_many :job_details, :dependent => :destroy
  has_many :jobs, :through => :job_details
end

class JobDetail < ActiveRecord::Base
  attr_accessible :job_id, :detail_id
  belongs_to :job
  belongs_to :detail
end

我的工厂:

factory :job do
  association     :tenant
  title           { Faker::Company.catch_phrase }
  company         { Faker::Company.name }
  company_url     { Faker::Internet.domain_name }
  purchaser_email { Faker::Internet.email }
  description     { Faker::Lorem.paragraphs(3) }
  how_to_apply    { Faker::Lorem.sentence }
  location        "New York, NY"
end

factory :detail do
  association :detail_type <--another Factory not show here
  description "Full Time"
end

factory :job_detail do
  association :job
  association :detail
end

我想要的是使用默认的“全职” Detail创建我的工作工厂。

我一直在努力遵循这一点,但没有任何运气: FactoryGirl Has Many through

我不确定应如何使用after_create通过 JobDetail 附加 Detail。

尝试这样的事情。 您想要构建一个detail对象并将其附加到作业的详细信息关联。 当您使用after_create ,创建的作业将被交给区块。 因此,您可以使用 FactoryGirl 创建详细信息对象,并将其直接添加到该作业的详细信息中。

factory :job do
  ...

  after_create do |job|
    job.details << FactoryGirl.create(:detail)
  end
end

我今天遇到了这个问题,我找到了解决方案。 希望这可以帮助某人。

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

这允许创建这样的工作

create(:job_with_details) #job created with 5 detail objects
create(:job_with_details, details_count: 3) # job created with 3 detail objects

这对我有用

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

然后后来

# 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

您可以通过以下方式解决此问题:

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

有了这个,你可以创建一个 job_with_details,它有选项来指定你想要的细节数量。 您可以阅读这篇有趣的文章以了解更多详细信息。

使用当前的 factory_bot(以前的 factory_girl)实现,一切都由 gem 处理,您不需要创建然后将记录推送到jobs.details 中。 你只需要这个

factory :job do
  ...

  factory :job_with_details do
    transient do
      details_count { 5 }
    end

    after(:create) do |job, evaluator|
      create_list(:detail, evaluator.details_count, jobs: [job])
      job.reload
    end
  end  
end

下面的代码将产生 5 个详细作业

 create(:job_with_details)

从 FactoryBot v5 开始,关联会保留构建策略。 关联是解决这个问题的最好方法, 文档中有很好的例子

FactoryBot.define :job do
  job_details { [association(:job_detail)] }
end

FactoryBot.define :detail do
  description "Full Time"
end

FactoryBot.define :job_detail do
  association :job
  association :detail
end

暂无
暂无

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

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