2016-06-10 5 views
1

Ich habe eine FactoryGirl-Fabrik für meine Appointment Modell. Ex:FactoryGirl Factory aufgrund von Logik in AR Rückruf

require 'faker' 

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

Das Appoinment Modell viele AppointmentAccess Instanzen hat. Sie erstellt sie in einem ActiveRecord-Rückruf für das Modell Appointment. Die AppointmentAccess ist ein Durchgangsmodell, das die Appointment mit einer User in Verbindung bringt.

Ich habe einen Rückruf an der Factory (siehe unten), aber ein Fehler nach wie vor aufgrund des AR Rückruf in dem Appointment Modell AR Rückruf ausgelöst wird vor dem factory Rückruf ausgeführt wird:

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 

Da die Der Callback des Modells läuft vor dem FactoryGirl-Callback, es gibt einen Fehler, weil die AppointmentAccess mit owner, die auf 1 gesetzt ist, noch nicht existiert. Hier ist meine factory Werk mit dem Callback (wie oben, mit Rückruf):

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 

Wie kann ich sicherstellen, dass vor dem Rückruf auf das Appointment Modell ausgeführt wird, dass die factory Rückruf ersten läuft (da die Activerecord-Logik erfordert, es)?

+0

Vielleicht hilft es Ihnen nicht mit Ihrem Problem, aber versuchen Sie Callbacks zu vermeiden – Sebastian

Antwort

0

Versuchen Sie, einen neuen AppointmentAccess Datensatz zusammen mit dem neuen Appointment mit dem Rückruf before(:create) zu initialisieren.

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 

Wenn die Appointment tatsächlich gespeichert wird, wird es auch die initialisierten AppointmentAccess zusammen mit ihm, an dem Speicherpunkt des after_create Rückruf im Modell ausgeführt wird.

+0

Das funktioniert, aber jetzt bekomme ich einen Stack Level zu tief, weil der TerminAccess eine Termin Factory erstellt. Wenn ich es aus der AppointmentAccess-Factory entferne, wird die Validierung nicht bestanden (ein Termin ist erforderlich). Ist das sinnvoll? – Noah

+0

Ja, es macht Sinn. Ich würde empfehlen, dass Sie sich Ihr Datenmodell ansehen, da Probleme wie diese tendenziell darauf hinweisen können, dass Sie einige zirkuläre Abhängigkeiten haben und dass Sie möglicherweise in der Lage sind, Dinge besser zu organisieren. Davon abgesehen, warum erstellen wir nicht (1) den "TerminAccess" manuell, z. 'appointment.appointment_accesses.build (...)' oder (2) versuche mit 'FactoryGirl.build (: verabredung_zugang, termin: nil)' 'die zweite Fabrik davon abzuhalten, den ersten –

+0

Still Stack Level Too Deep aufzurufen. Die Validierung wird nicht bestanden, wenn ich sie nicht in AppointmentAccess einstelle, aber da sie den Termin auf dem Terminaccess im 'before (: create)' festlegt, dass sie keinen neuen Termin erstellen würde, wäre das der Ziel zumindest, oder? – Noah

Verwandte Themen