2013-04-14 11 views
10

Ecco un esempio dalla factorygirl documentation:factorygirl definiscono attributo con il metodo invitando un altro stabilimento

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

In questo esempio, user invoca un altro stabilimento. Quello che vorrei fare è effettivamente chiamare user.id, ma impostarlo come la definizione di un attributo. Ecco un esempio ridotto all'osso:

**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 

Ho cercato di incorporare la parte della documentazione che discute gli alias, ma senza fortuna:

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

Mi sento come se'(speranza?) m chiudi qui, ma qualsiasi intuizione è apprezzata. Grazie.

MODIFICA: questo codice ottiene le mie specifiche in esecuzione!

**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 

e passa il mio it { should be_valid } spec, così sembra che la fabbrica va bene, anche se penso di avere un po 'di refactoring nelle specifiche stesso quando sto chiamando FactoryGirl.create.

Il codice sopra incorpora i suggerimenti di mguymon. Grazie!

aggiornamento finale

Dopo andando avanti e rileggendo Hartl's discussion on model associations, sono stato in grado di mettere questa materia per riposare. Quello che ho sopra era tecnicamente valido, ma in realtà non ha trasmesso correttamente gli attributi quando ho creato o creato lavori nelle mie specifiche. Ecco cosa mi avrebbe dovuto avere:

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

Il mio problema derivava anche da come stavo creando fabbriche nella mia spec, quindi ecco come avrei fatto (ma non era ... sigh):

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

Sembra che io non abbia esplicitamente il association :user nella mia fabbrica, né ho bisogno del blocco before dall'alto.

Per inciso, ho anche imparato che posso mettere a punto includendo puts @job all'interno di un expect dichiarazione, oppure chiamare @job.assignee_id per assicurarsi che gli attributi vengono caricati correttamente. Quando viene eseguita questa particolare specifica, l'istruzione puts verrà emessa direttamente dallo F o dallo . dalla specifica.

+0

scusate, ma potete visualizzare la traccia dello stack di eccezioni? grazie – ted

risposta

14

Per l'ultima versione di factorygirl, utilizzare association per mappare ad altri modelli ActiveRecord:

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

Questo è retta dalla the docs.


Da l'errore che hai postato, si sta affermando che si sta tentando di ottenere il user.id ma user non è un'istanza ActiveRecord, ma un proxy da factorygirl. Non riceverai questo errore se utilizzi il metodo association. Se devi accedere direttamente a un modello, devi prima costruirlo manualmente.È possibile farlo passando un blocco in fabbrica:

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

Sembra che si sta tentando di associare lo stesso modello due volte, per questo si può utilizzare before_create callback per creare un modello utente e assegnare a user e assignee:

factory :job do 

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

Grazie per la risposta e il collegamento. Anche con l'associazione (di cui sono sicuro è necessario), sto ancora ottenendo un errore "id" del metodo non definito ". – aceofbassgreg

+0

La tua modifica ha funzionato. Ora che le mie specifiche sono finalmente in esecuzione, ho bisogno di passare e correggere alcuni guasti fastidiosi causati da utenti duplicati ... – aceofbassgreg

+0

Si scopre che non ho bisogno di 'before (: create), né ho bisogno di creare un utente dal Fabbrica. Sebbene la mia fabbrica fosse testata come valida, non stava caricando correttamente gli attributi nei lavori che stavo creando o costruendo nelle mie specifiche (l'ho verificato usando puts @job nelle specifiche). Ho aggiunto il codice corretto (o, almeno una versione migliore ... forse c'è una versione 'più corretta') alla mia domanda, ma sto lasciando la tua risposta come risposta verificata poiché ho esplicitamente bisogno di associare il assegnatario con l'utente e non lo farebbe senza il tuo aiuto. – aceofbassgreg

Problemi correlati