J'ai eu du mal à mettre en place une relation has_many/through
à l'aide de Factory Girl.
J'ai les modèles suivants:
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
Mon usine:
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
Ce que je veux, c'est que ma fabrique de jobs soit créée avec une valeur par défaut Detail
de "Temps plein".
J'ai essayé de suivre cela, mais je n'ai pas eu de chance: FactoryGirl Has Many through
Je ne suis pas sûr de la manière dont le after_create
devrait être utilisé pour attacher le détail via JobDetail.
Essayez quelque chose comme ça. Vous souhaitez créer un objet detail
et l'ajouter à l'association de détail du travail. Lorsque vous utilisez after_create
, le travail créé sera renvoyé au bloc. Vous pouvez donc utiliser FactoryGirl pour créer un objet de détail et l'ajouter directement aux détails de ce travail.
factory :job do
...
after_create do |job|
job.details << FactoryGirl.create(:detail)
end
end
J'ai fait face à ce problème aujourd'hui et j'ai trouvé une solution. J'espère que ça aide quelqu'un.
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
Cela permet de créer un travail comme celui-ci
create(:job_with_details) #job created with 5 detail objects
create(:job_with_details, details_count: 3) # job created with 3 detail objects
Cela a fonctionné pour moi
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
Puis plus tard
# 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
Vous pouvez résoudre ce problème de la manière suivante:
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
Avec cela, vous pouvez créer un job_with_details, qui a des options pour spécifier le nombre de détails que vous voulez. Vous pouvez lire cet article intéressant pour plus de détails.