2012-07-18 9 views
6

Quiero secar los ganchos después de crear/construir en mi fábrica:factorygirl seco después de crear/construir ganchos

FactoryGirl.define do 

    factory :poll do 

    sequence :title do |n| 
     "MyPollTitle#{n}" 
    end 
    sequence :description do |n| 
     "MyPollDescription#{n}" 
    end 
    user 

    factory :poll_with_answers do 

     ignore do 
     answers_count 2 
     end 

     after(:build) do |poll, evaluator| 
     evaluator.answers_count.times do 
      poll.answers << build(:answer, poll: poll) 
     end 
     end 

     after(:create) do |poll, evaluator| 
     evaluator.answers_count.times do 
      poll.answers << create(:answer, poll: poll) 
     end 
     end 
    end 
    end 
end 

El problema que estaba enfrentando es que parece que no puedo definir métodos de FG? ¿Idea cómo SECAR esto?

Respuesta

6

En primer lugar, after(:create) llama implícitamente after(:build), al menos en las versiones recientes de factorygirl:

después (: build) - llamado después de una fábrica se construye (a través de FactoryGirl.build, FactoryGirl.create)

https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#callbacks

Así, en su caso, el siguiente código debe ser suficiente:

after(:build) do |poll, evaluator| 
    evaluator.answers_count.times do 
    poll.answers << build(:answer, poll: poll) 
    end 
end 

Sin embargo, after(:build) no se activa cuando se utiliza en lugar de build_stubbed()build(), que es lo que estaba tratando de hacer cuando me encontré con este hilo. Para secar el código, resulta que se puede utilizar el método de callback() llamar el mismo bloque para varios métodos:

factory :user do 
    callback(:after_build, :after_stub) do |user| 
    do_something_with(user) 
    end 
end 
1

Esto podría ser un truco barato, pero se puede crear una lambda en la segunda fábrica:

factory :poll_with_answers do 
    ignore do 
    answers_count 2 
    end 

    make_answers = lambda do |poll, evaluator, method| 
    evaluator.answers_count.times do 
     poll.answers << send(method, :answer, poll: poll) 
    end 
    end 

    after(:build) do |poll, evaluator| 
    make_answers.call poll, evaluator, :build 
    end 

    after(:create) do |poll, evaluator| 
    make_answers.call poll, evaluator, :create 
    end 
end 

No estoy del todo contento con este patrón, pero al menos está seco la materia para arriba.

+0

Se debe hacer el truco. Es bastante equivalente a su código, por lo que si el evaluador es nulo en la versión de lambda, entonces también debería ser nulo en su versión. ¿Pueden darme el código de trabajo original y el código que obtiene nils (también stacktrace)? No tengo suficiente información para depurar actualmente. –

+0

No necesita invertir más trabajo en esto, no importa mucho, básicamente quería comprobar si hay un atajo. De todos modos, hice una idea en https://gist.github.com/3140033 donde puedes ver los modelos, el resto es 1: 1. – wintersolutions

+0

Bueno, no te preocupes, pero después de verificar el código, no tengo idea de qué 'evaluador' es :) –