2012-06-01 16 views
10

Tôi mới tham gia FactoryGirl và tôi đang thử kịch bản đơn giản sau đây?Nhà máy Cô gái tạo liên kết với đối tượng hiện có

factory :female, :class => Gender do 
    code 'Female' 
end 

factory :male, :class => Gender do 
    code 'Male' 
end 

factory :papas, :class => Customer do 
    first_name 'Jim' 
    last_name 'Papas' 
    association :gender, :factory => :male, :strategy => :build 
end 

factory :dumas, :class => Customer do 
    first_name 'Mary' 
    last_name 'Dumas' 
    association :gender, :factory => :female, :strategy => :build 
end 

Sau đó, trong thử nghiệm của tôi:

create(:male) 
create(:female) 
create(:papas) 
create(:dumas) 

Lưu ý rằng lớp khách hàng có assocation belongs_toGender lớp và một quy tắc xác nhận rằng nói rằng gender_id nên có mặt. Tôi cũng có một xác nhận trên Gender lớp cho tính duy nhất trên mã.

Trên create(:papas) tuyên bố ở trên, trong thử nghiệm của mình, tôi nhận được lỗi rằng Customer sẽ được tạo không hợp lệ, vì gender_idnil.

Nếu tôi loại bỏ các hiệp hội :strategy => :build trên Customer:papas nhà máy với giới tính, sau đó tôi sẽ gặp phải lỗi, mà khi cố gắng tạo :papas, mã cho giới đã tồn tại.

Tôi cần làm gì để thử nghiệm của tôi tạo dữ liệu theo yêu cầu ở trên?

Lưu ý rằng tôi muốn có giới tính được tạo mà không có khách hàng, trong các thử nghiệm khác. Đừng nói với tôi để tạo ra các khách hàng với nhà máy tạo ra các lệnh và để cho khách hàng tạo ra các giới tính cùng một lúc. Điều này sẽ không hiệu quả nếu tôi cố gắng tạo ra hai khách hàng cùng giới tính.

Ngoài ra, phải có một câu trả lời tốt hơn so với một:

@male = create(:male) 
@female = create(:female) 
create(:papas, :gender => @male) 
create(:dumas, :gender => @female) 

(.? Khi sử dụng đồ đạc những điều này đã sẵn sàng out-of-the-box: Tôi phải trở về cố định)

Trả lời

14

Bạn có thể đạt được những gì bạn muốn bằng cả hai không sử dụng nhà máy cho các trường hợp Giới tính của bạn và sử dụng gọi lại trong nhà máy Khách hàng của bạn.

Bạn không đạt được nhiều thứ từ nhà máy Giới tính khi nó đứng (mặc dù tôi đánh giá cao nó có thể được đơn giản hóa cho mục đích đặt câu hỏi này). Bạn có thể chỉ là một cách dễ dàng làm được điều này để có được một Giới tính:

Gender.find_or_create_by_code!('Male') 

Sau đó tại nhà máy khách hàng của bạn, bạn có thể sử dụng một trước khi gọi lại để thiết lập Giới tính:

factory :dumas, :class => Customer do 
    first_name 'Mary' 
    last_name 'Dumas' 
    before_create do |customer| 
    customer.gender = Gender.find_or_create_by_code!('Female') 
    end 
end 

Định dạng cho việc sử dụng callbacks trong factory_girl có thời gian gần đây đã thay đổi vì vậy nếu bạn đang sử dụng 3.3 hay muộn bạn sẽ cần phải làm:

before(:create) do |customer| 

thay vì before_create.

Nếu tạo giới tính phức tạp hơn ví dụ của bạn, bạn vẫn có thể tạo giới tính bằng cách sử dụng nhà máy nhưng kết nối chúng với khách hàng bằng cách sử dụng gọi lại bằng cách sử dụng find_by_code! insteand của find_or_create_by_code!.

+0

Mặc dù khá dài dòng vs đồ đạc, câu trả lời của bạn là đúng. Tôi đã sử dụng cô gái nhà máy trong hai tháng qua và vẫn còn dự án tiếp theo của tôi sẽ được với đồ đạc! –

+1

Lợi thế bạn có thể tìm thấy với các nhà máy là nếu bạn cần tạo nhiều khách hàng khác nhau. Bạn có thể có một nhà máy male_customer và female_customer và sử dụng các nhà máy đó làm nhà máy cha mẹ cho các khách hàng khác nhau của bạn - làm giảm đáng kể độ dài. Vui mừng nó làm việc mặc dù! – Shadwell

5

Các ignore khối có thể được sử dụng để bọc này lên cũng như:

factory :dumas, :class => Customer do 
    ignore do 
    female { Gender.find_by_code('Female') || create(:female) } 
    end 

    first_name 'Mary' 
    last_name 'Dumas' 
    gender { female } 
end 
5

ignore đã được chấp nhận và sẽ bị loại bỏ trên phiên bản 5 của Factory Girl.

Thay vào đó, bạn có thể sử dụng transient attributes:

factory :dumas, :class => Customer do 
    transient do 
    female { Gender.find_by_code('Female') || create(:female) } 
    end 

    first_name 'Mary' 
    last_name 'Dumas' 
    gender { female } 
end 
Các vấn đề liên quan