2013-01-21 21 views
28

ファクトリーガールを使用してhas_many/throughの関係を設定することに苦労しています。工場の女の子: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経由で詳細を取り付けるために使用する必要があるかどうかはわかりません。

答えて

30

このようなものを試してみてください。 detailオブジェクトを作成し、それをジョブの詳細な関連付けに追加するとします。 after_createを使用すると、作成されたジョブがブロックに生成されます。 FactoryGirlを使用してディテールオブジェクトを作成し、それをそのジョブの詳細に直接追加することができます。

factory :job do 
    ... 

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

ありがとうございました。 1つの質問 - after_createの動作を追加しますが、 'DEPRECATION WARNING:' detail_id '属性を作成しようとしています。モデルに任意の属性を書き込むことは推奨されていません。 'attr_writer'などを使ってください。 – cman77

+11

私はこれが古いと知っていますが、FactoryGirlでは 'after_create'の代わりに' after(:create) 'という形式のコールバックを使用します。残りの答えはエラーなく動作するはずです。 – Arel

+0

'after(:create)'コールバックの詳細:http://robots.thoughtbot.com/get-your-callbacks-on-with-factory-girl-3-3 – Brian

2

これは私が今日、この問題に直面し、私は解決策を見つけた

# 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

私はこれが古かったことを知っていますが、ここで受け入れられている答えよりもこれをより良くするものについて興味がありますか? – rorykoehler

+0

元の回答を読んだとき、私の好みの例では十分な情報がありませんでした。これは 'detail:@ detail'オプションの有無にかかわらず' create:job_with_detail'を使うことができるので、その答えの上に追加機能を追加します。 – Nate

4

後に続いて、私のため

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 

を働きました。これが誰かを助けることを望みます。

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 
+0

は今のところ最新のものすべてでうまくいきます(レール5、rspec 3.5、factorygirl 4.8) – jpwynn

0

ような仕事を作成することができます。これにより

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を作成することができ、それが持っていますあなたが望む細部の数を指定するオプション。 詳しくはthis interesting articleをご覧ください。

関連する問題