2012-05-02 7 views
18

In un'applicazione Rails, somministrati tre modelli d'uso, l'articolo e revisore con le seguenti relazioni e le convalide:Come ragazza all'utente fabbrica per creare elenchi associati con un has_many con una convalida che lo richiede il creare

class User < ActiveRecord::Base 
    has_many :articles 
    has_many :reviewers 
end 

class Reviewer < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :article 
end 

class Article < ActiveRecord::Base 
    belongs_to :user 
    has_many :reviewers 

    validate :has_reviewers? 

    def has_reviewers? 
    errors.add(:base, "article must have at least one reviewer.") if self.reviewers.blank? 
    end 
end 

e le seguenti fabbriche che utilizzano il DSL più recente:

FactoryGirl.define do 

    factory :user do 
    name { (8...20).map{ ('a'..'z').to_a[rand(26)] }.join } 
    age { Kernel.rand(100) } 
    end 

    factory :article do 
    body "This is the article content" 
    title "This is the title" 
    user 
    after_create do |article| 
     article.reviewers = create_list(:user, 2) 
    end 
    end 

    factory :reviewer do 
    user 
    article 
    state { ["published","draft","rejected","archived"][Kernel.rand(4)] } 
    end 

end 

la fabbrica per creare l'articolo non funziona perché la convalida non riesce prima di creare i revisori:

> FactoryGirl.create(:article) 
ActiveRecord::RecordInvalid: Validation failed: article must have at least one reviewer. 

Ho fatto più tentativi di quanto vorrei ammettere cercando di superare questo ostacolo, ma sono bloccato! Un'idea che avevo era quella di creare i revisori come questo:

factory :article do 
    body "This is the article content" 
    title "This is the title" 
    user 
    reviewers {|a| [FactoryGirl.create(:reviewer, article: a)] } 
    end 

ma in questo contesto, la "a" non è l'istanza. Quindi non funziona neanche, come prima.

risposta

3
factory :article do 
    reviewers {|a| [a.association(:reviewer)] } 
end 

o

factory :article do 
    before_create do |a| 
    FactoryGirl.create(:reviewer, article: a) 
    end 
end 
+0

Quando provo questo, ottengo: SystemStackError: livello di strato troppo in profondità. Sembra che quando la fabbrica di revisori viene licenziata, non sappia dell'articolo, quindi prova a creare un altro articolo. – Blizzo

+0

@ Blora È possibile rimuovere la creazione dell'articolo dalla fabbrica del revisore o utilizzare before_create. Ho modificato la mia risposta per riflettere questo. – Unixmonkey

+0

Ho dato un secondo colpo anche al secondo esempio dopo averlo aggiunto e ottenuto l'errore di convalida: ActiveRecord :: RecordInvalid: convalida non riuscita: l'articolo deve avere di nuovo almeno un revisore – Blizzo

22

ho ripubblicato in questo corso sulla pagina GitHub Factory Girl come un problema e lavorato la mia strada intorno alla risposta:

before_create do |article| 
    article.reviewers << FactoryGirl.build(:reviewer, article: article) 
end 

La chiave stava facendo in un before_create, quindi le convalide non sono ancora state lanciate e assicurandosi di inserire il revisore appena creato nell'elenco delle recensioni sull'istanza che si sta creando. Grazie a Unixmonkey per rispondere e mantenere me provare cose nuove :)

https://github.com/thoughtbot/factory_girl/issues/369#issuecomment-5490908

+0

Avevo un problema simile e questo l'ha risolto. Grazie! – ryanpitts1

1

La nuova sintassi è:

before(:create) do |article| 
    article.reviewers << FactoryGirl.build(:reviewer, article: article) 
end 
Problemi correlati