2016-06-10 3 views
1

Appointment 모델의 FactoryGirl 팩토리가 있습니다. 예 :AR 콜백의 논리로 인해 FactoryGirl 팩토리가 실패합니다.

require 'faker' 

FactoryGirl.define do 
    factory :appointment do |f| 
    f.name { 'Pending Appointment' } 
    end 
end 

Appoinment 모델은 많은 AppointmentAccess 경우가 있습니다. Appointment 모델의 ActiveRecord 콜백에 생성합니다. AppointmentAccessAppointmentUser과 관련된 통과 모델입니다.

나는 공장 (아래 참조)에 콜백을 추가했지만 오류가 여전히 FactoryGirl 콜백 이전에 실행으로 인해 AR 콜백에 Appointment 모델의 AR 콜백에서 발생되는 다음부터

class Appointment < ActiveRecord::Base 
    has_many :appointment_accesses 
    has_many :users, through: :appointment_accesses 

    after_create :example_callback 

    protected 

    def example_callback 
    owner = self.appointment_accesses.find_by(owner: 1) 

    owner.name 
    end 
end 

모델의 콜백이 FactoryGirl 콜백보다 먼저 실행되고 있는데 AppointmentAccessowner으로 설정된 모델이 아직 존재하지 않기 때문에 오류가 발생합니다. 다음은 콜백 내 FactoryGirl 공장 (위와 동일 콜백으로)입니다 :

require 'faker' 

FactoryGirl.define do 
    factory :appointment do |f| 
    f.name { 'Pending Appointment' } 

    after(:create) do |appointment| 
     FactoryGirl.create(:appointment_access, appointment: appointment) 
    end 
    end 
end 

나는 액티브 논리가 필요하기 때문에 FactoryGirl 콜백 (처음 실행되는지는 Appointment 모델에 콜백하기 전에 실행해야 할 수있는 방법 그것)?

+0

어쩌면 당신의 문제에 도움이되지 않지만 콜백을 피하려고합니다. – Sebastian

답변

0

before(:create) 콜백을 사용하여 새 레코드를 새 Appointment과 함께 초기화 해보십시오. Appointment이 실제로 저장 될 때, 그것은 또한 그와 함께 초기화 AppointmentAccess을 절약 할 수

require 'faker' 

FactoryGirl.define do 
    factory :appointment do |f| 
    f.name { 'Pending Appointment' } 

    before(:create) do |appointment| 
     # initializes a new AppointmentAccess and adds it to the collection 
     appointment.appointment_accesses << FactoryGirl.build(:appointment_access) 
    end 
    end 
end 

되는 모델의 after_create 콜백이 실행됩니다 가리 킵니다.

+0

이것은 작동하지만, 이제는 AppointmentAccess가 Appointment 팩토리를 생성하기 때문에 Stack Level Too Deep이 발생합니다. AppointmentAccess 팩토리에서 제거하면 유효성 검사를 통과하지 않습니다 (약속 필요). 말이 돼? – Noah

+0

예. 이와 같은 문제는 순환 의존성이 있다는 것을 나타내며 더 잘 정리할 수있는 데이터 모델을 살펴 보는 것이 좋습니다. 즉, (1) 수동으로 'AppointmentAccess'를 빌드하십시오. 두 번째 팩토리가 첫 번째 –

+0

스틸 스택 레벨을 너무 깊게 호출하는 것을 중지하려면 'FactoryGirl.build (: appointment_access, appointment : nil)'을 사용하십시오. AppointmentAccess에서 설정하지 않으면 유효성 검사가 통과하지 않지만 'before (: create)'에서 AppointmentAccess의 약속을 설정하기 때문에 새 약속을 만들지 않을 것이라고 생각할 것입니다. 목표는 적어도, 맞습니까? – Noah

관련 문제