2013-04-30 2 views
22

이것은 아마도 간단하지만 어딘가에서 예제를 찾을 수 없습니다. 나는 프로필을 만들 때FactoryGirl은 연결된 객체의 속성을 무시합니다.

FactoryGirl.define do 
    factory :profile do 
    user 

    title "director" 
    bio "I am very good at things" 
    linked_in "http://my.linkedin.profile.com" 
    website "www.mysite.com" 
    city "London" 
    end 
end 

FactoryGirl.define do 
    factory :user do |u| 
    u.first_name {Faker::Name.first_name} 
    u.last_name {Faker::Name.last_name} 

    company 'National Stock Exchange' 
    u.email {Faker::Internet.email} 
    end 
end 

은 내가 사용자의 일부를 대체 할 일은 원하는 것은 속성 :

내가 두 개의 공장을 가지고

p = FactoryGirl.create(:profile, user: {email: "[email protected]"}) 

또는 이와 유사한

,하지만 난 할 수 없습니다 구문을 올바르게 얻으십시오. 오류 :

ActiveRecord::AssociationTypeMismatch: User(#70239688060520) expected, got Hash(#70239631338900) 

는 내가 프로필과 연결 먼저 사용자를 생성하고이 작업을 수행 할 수 있습니다 알고,하지만 난 더 나은 방법이 있어야합니다 생각했다.

또는이 작동합니다

p = FactoryGirl.create(:profile, user: FactoryGirl.create(:user, email: "[email protected]")) 

하지만 지나치게 복잡한 것 같다. 연관된 속성을 재정의하는 더 간단한 방법은 없습니까? 올바른 구문은 무엇입니까 ??

답변

6

콜백 및 일시적인 특성을 사용하여이 작업을 수행 할 수 있다고 생각합니다. 당신과 같이 프로필 공장을 수정하는 경우 :

FactoryGirl.define do 
    factory :profile do 
    user 

    ignore do 
     user_email nil # by default, we'll use the value from the user factory 
    end 

    title "director" 
    bio "I am very good at things" 
    linked_in "http://my.linkedin.profile.com" 
    website "www.mysite.com" 
    city "London" 

    after(:create) do |profile, evaluator| 
     # update the user email if we specified a value in the invocation 
     profile.user.email = evaluator.user_email unless evaluator.user_email.nil? 
    end 
    end 
end 

은 당신이 원하는 결과를 다음과 같이 그것을 호출하고 얻을 수 있어야합니다 : 그래도, 그것을 테스트하지 않은

p = FactoryGirl.create(:profile, user_email: "[email protected]") 

.

+0

고마워요.하지만 모든 속성에서 작동하고 싶습니다. 그래서 각 코드에 대해 코드를 작성하고 싶지는 않습니다. 아마 아무도 이걸 필요로하지 않을거야. – bobomoreno

+2

당신의 예제에 오류가 있다고 생각합니다. 'after (: create)'를'profile.user.email = evaluator.user_email '로 변경하십시오 (evaluator.user_email.nil?가 아닌 경우). – Kelly

18

FactoryGirl의 제작자 중 한 사람에 따르면 동적 도우미를 연결 도우미 (Pass parameter in setting attribute on association in FactoryGirl)에 전달할 수 없습니다. 당신이 원하는 거의 같은

FactoryGirl.define do 
    factory :profile do 
    transient do 
     user_args nil 
    end 
    user { build(:user, user_args) } 

    after(:create) do |profile| 
     profile.user.save! 
    end 
    end 
end 

그런 다음 당신이 그것을 호출 할 수 있습니다 :

그러나이 같은 것을 할 수 있어야

p = FactoryGirl.create(:profile, user_args: {email: "[email protected]"}) 
+2

좋은 답변입니다. 최신 Rails 버전을 준수하도록 업데이트 하시겠습니까? 예 : "DEPRECATION WARNING :'# ignore'는 더 이상 사용되지 않으며 5.0에서 제거 될 것입니다." 이 대답을 구현할 때. –

+0

레일 5에 이미이 문제가 있습니다 –

+0

"무시"대신 "일시적"을 사용하여 경고를 없앨 수 있습니다 –

3

처음 사용자를 생성하여 해결 한 다음 프로필 :

my_user = FactoryGirl.create(:user, user_email: "[email protected]") 
my_profile = FactoryGirl.create(:profile, user: my_user.id) 

그래서,이 두 줄에 걸쳐 분할 문제에서와 거의 동일합니다. 실제 차이점은 ".id"에 대한 명시 적 액세스뿐입니다. 레일 5로 테스트했습니다.

관련 문제