Factory Girl: Как создать ассоциацию has_many/through
Я боролся с настройкой отношения has_many/through
с помощью Factory Girl.
У меня есть следующие модели:
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:
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
Я хочу, чтобы моя работа Factory создавалась с использованием по умолчанию Detail
в режиме полного времени.
Я пытался следовать этому, но не повезло:
FactoryGirl имеет много результатов
Я не уверен, как использовать after_create
для прикрепления детали через JobDetail.
Ответы
Ответ 1
Попробуйте что-нибудь подобное. Вы хотите создать объект detail
и добавить его в ассоциацию деталей задания. Когда вы используете after_create
, созданное задание будет передано блоку. Таким образом, вы можете использовать FactoryGirl для создания подробного объекта и напрямую добавлять его в эту информацию.
factory :job do
...
after_create do |job|
job.details << FactoryGirl.create(:detail)
end
end
Ответ 2
Сегодня я столкнулся с этой проблемой, и я нашел решение. Надеюсь, это поможет кому-то.
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
Ответ 3
Это сработало для меня
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
Ответ 4
Вы можете решить эту проблему следующим образом:
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, в котором есть опции, чтобы указать, сколько деталей вы хотите.
Вы можете прочитать эту интересную статью для более подробной информации.