2012-07-18 6 views
6

Tôi muốn khô cạn sau khi tạo/xây dựng móc trong nhà máy của tôi:FactoryGirl DRY sau khi tạo/xây dựng móc

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 

Vấn đề tôi đang phải đối mặt là có vẻ như tôi không thể xác định phương pháp trong FG? Ý tưởng làm thế nào để DRY này lên?

Trả lời

6

Thứ nhất, after(:create) ngầm gọi after(:build), ít nhất là trong các phiên bản gần đây của FactoryGirl:

sau (: xây dựng) - gọi sau khi một nhà máy được xây dựng (thông qua FactoryGirl.build, FactoryGirl.create)

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

Vì vậy, trong trường hợp của bạn, đoạn code sau nên là đủ:

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

Tuy nhiên, after(:build) không được kích hoạt khi bạn sử dụng build_stubbed() thay vì build(), đó là những gì tôi đã cố gắng làm khi tôi gặp chủ đề này. Để xử lý mã này, hóa ra bạn có thể sử dụng phương thức callback() để gọi cùng một khối cho nhiều phương thức:

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

Đây có thể là một thủ thuật rẻ tiền, nhưng bạn có thể tạo ra một lambda trong nhà máy thứ hai:

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 

Tôi không ở tất cả hài lòng với mô hình này, nhưng ít nhất nó DRY của cụ lên.

+0

Cần thực hiện thủ thuật. Nó khá giống với mã của bạn, vì vậy nếu bộ đánh giá là nil trong phiên bản lambda, thì nó cũng không phải là nil trong phiên bản của bạn. Bạn có thể nắm cho tôi cả mã làm việc ban đầu và mã nhận được nils (cũng là stacktrace). Hiện tại tôi không có đủ thông tin để gỡ lỗi. –

+0

Bạn không cần phải đầu tư thêm bất kỳ công việc nào nữa, điều này không quan trọng lắm, về cơ bản tôi chỉ muốn kiểm tra xem liệu có một lối tắt hay không. Dù sao tôi đã thực hiện một ý chính tại https://gist.github.com/3140033 nơi bạn có thể xem các mô hình, phần còn lại là 1: 1. – wintersolutions

+0

Vâng, không phải lo lắng, nhưng sau khi kiểm tra mã, tôi không có ý tưởng gì 'evaluator' là :) –