2013-04-14 6 views
10

上のメソッドを呼び出すことで、属性を定義するにはFactoryGirl documentationからの例です。この例ではFactoryGirlはここで別の工場

FactoryGirl.define do 
    factory :post do 
    name "Post name" 
    user 
    end 
end 

userは別の工場を呼び出しています。私がしたいことは効果的にuser.idを呼び出すことですが、それを属性の定義として設定することです。ここで削ぎ落とした例です:

**models/job.rb** 
    ... 
    belongs_to :assignee, :class_name => "User" 
    belongs_to :user 
    ... 
    attr_accessible :assignee_id, :user_id 
    ... 
end 


**factories/jobs.rb** 
FactoryGirl.define do 
    factory :job do 
    assignee_id user.id  #what I would like to do, but triggers "undefined method 'id'" error 
    user_id user.id   #user_id is an attribute of the model and is the job assignor 
end 

私はしかし、運と、エイリアスを論じて文書の一部を組み込むために試してみた:

FactoryGirl.define do 
    factory :user, :aliases => [:assignee] do 
    .... 

私は(希望?)のように感じて、私は」私はここに閉じますが、どんな洞察も高く評価されます。ありがとう。

編集:このコードは、私の仕様を実行します!

**factories/jobs.rb** 

FactoryGirl.define do 
    factory :job do 
    before(:create) do |job| 
     user = FactoryGirl.create(:user) 
     job.assignee = user 
     job.user = user 
    end 

    association :assignee, factory: :user 
    association :user, factory: :user 
    sequence(:user_id) { |n| n } 
    sequence(:assignee_id) { |n| n } 
    ... 
end 

そして、それは私のit { should be_valid }スペックを渡すので、私は、私はFactoryGirl.createを呼んだとき、私はスペック自体にいくつかのリファクタリングを持っていると思いますけれども、工場が細かいようです。

上記のコードには、mguymonの提案が組み込まれています。ありがとう!

FINAL UPDATE

帰るとHartl's discussion on model associations再読んだ後、私は休むためにこの問題を置くことができました。私が上記のことはtechincally有効だったが、実際に私の仕様でジョブを構築または作成したときに属性を正しく渡さなかった。ここで私が持っていたはずですものだ:

FactoryGirl.define do 
    factory :job do 
    association :assignee, factory: :user 
    user 
    end 
end 

私の問題は、また、私は私の仕様で工場を作っていた方法から生じ、ので、ここで私はそれをやっている必要があります方法です(ただし、ため息...ありませんでした):

let(:user) { create(:user) } 
    before { @job = create(:job, user: @user) } 

明示的に私の工場でassociation :userを持っている必要はないと思いますし、上記のbeforeブロックが必要ではありません。

はさておき、私はまた、私はexpectステートメント内puts @jobを含めることによって、デバッグ、または属性が正しくロードされていることを確認するために@job.assignee_idを呼び出すことができることを学びました。その特定の仕様が実行されると、putsステートメントはFまたは.によって仕様から正しく出力されます。 FactoryGirlの最新版について

+0

申し訳ありませんが、例外スタックトレースを表示できますか?ありがとうございました – ted

答えて

14

、他のActiveRecordのモデルにマッピングするassociationを使用します。

factory :job do 
    # ... 
    association :assignee, factory: :user 
end 

これはストレートthe docsからです。あなたは、あなたがuser.idを取得しようとしているが、userはActiveRecordのインスタンスが、FactoryGirlからプロキシではありません述べて掲載エラーから


associationメソッドを使用している場合、このエラーは発生しません。モデルに直接アクセスする必要がある場合は、まずモデルを手動で構築する必要があります。あなたの工場でブロックを渡すことによってこれを行うことができます。

factory :job do 
    assignee_id { FactoryGirl.create(:user).id } 
end 

あなたは二度同じモデルを関連付けるしようとしているように見え、このためにあなたはUserモデルを作成するためにbefore_createコールバックを使用することができますし、userに割り当てますとassignee

factory :job do 

    before(:create) do |job| 
     user = FactoryGirl.create(:user) 
     job.assignee = user 
     job.user = user 
    end 
end 
+0

答えとリンクありがとう。アソシエーション(私は確かに必要です)でも、私はまだ "未定義のメソッド 'ID'"エラーが発生しています。 – aceofbassgreg

+0

あなたの編集がトリックでした。私の仕様が最終的に実行されたので、私は重複したユーザによって引き起こされるいくつかの面倒な失敗を修正する必要があります... – aceofbassgreg

+0

私は 'before(:create)を必要としませんでした。工場。私の工場は有効であるとテストされていましたが、私が作成したり作成したジョブに属性を適切にロードしていませんでした(仕様内でputs @jobを使って検証しました)。私は正しいコードを追加しました(または、少なくともより良いバージョン...多分もっと正確なバージョンがあります)。私の質問には答えが残っていますが、私は明示的にあなたの助けなしにそれを得ないであろう。 – aceofbassgreg

関連する問題