2012-10-24 34 views
6

Tôi đang cố gắng tìm ra cách viết một nhà máy thuộc 2 mô hình khác nhau mà mỗi mô hình phải có cùng một mô hình gốc. Dưới đây là đoạn code mẫu giả tạo:Liên kết phức tạp FactoryGirl với nhiều mô hình

class User < ActiveRecord::Base 
    has_many :widgets 
    has_many :suppliers 

    attr_accessible :username 
end 

class Widget < ActiveRecord::Base 
    belongs_to :user 
    has_many :parts 

    attr_accessible :name 
end 

class Supplier < ActiveRecord::Base 
    belongs_to :user 
    has_many :parts 

    attr_accessible :name 
end 

class Part < ActiveRecord::Base 
    belongs_to :supplier 
    belongs_to :widget 

    attr_accessible :name 
end 

Dưới đây là những gì tôi có cho đến nay:

factory :user do 
    name 'foo' 
end 

factory :widget do 
    association :user 
    name 'widget' 
end 

factory :supplier do 
    association :user 
    name 'supplier' 
end 

factory :part do 
    association :widget 
    association :supplier 
    name 'part' 
end 

Vấn đề ở đây là các part.widget.user != part.supplier.user và họ phải được như vậy.

Tôi đã thử những điều sau đây không có thành công:

factory :part do 
    association :widget 
    association :supplier, user: widget.user 
    name 'part' 
end 

gợi ý Bất kỳ? Hay tôi phải sửa đổi nó sau khi tôi tạo ra một phần?

Cảm ơn bạn

Trả lời

7

Tôi tin rằng bạn có thể làm điều này với một callback:

factory :part do 
    association :widget 
    association :supplier 
    name 'part' 
    after(:create) do |part| 
    user = FactoryGirl.create(:user) 
    part.widget.user = part.supplier.user = user 
    end 
end 

Xem thêm: Get two associations within a Factory to share another association

+0

Cảm ơn rất nhiều. Tôi đã kết thúc bằng cách sử dụng 'after (: build)' và 'part.widget.user = part.supplier.user' theo cách đó tôi không tạo 3 người dùng :) –

+0

Thật tuyệt khi nó hoạt động! Tôi không chắc lắm. Dường như với tôi thì phải có một cách sạch hơn để làm điều đó. –

+0

Đó là những gì tôi nghĩ quá, nhưng 'hiệp hội: nhà cung cấp, người dùng: widget.user' không hoạt động có thể là một cái gì đó để xem xét cho một bản vá –

0

lựa chọn khác là sử dụng các biến tạm thời để cho phép một đối tượng liên quan để được thông qua in.

Tôi thường sử dụng hai biến:

  • Biến để giữ liên kết được sử dụng trong nhà máy
  • Biến boolean để cho biết có tạo giá trị mặc định cho biến liên kết - có thể không cần thiết trong trường hợp cụ thể của bạn, nhưng có thể rất hữu ích

Đây là cách nó sẽ nhìn:

factory :part do 
    transient do 
    # this variable is so we can specify the user 
    with_user { no_user ? nil : Factory.create(:user) } 

    # this variable allows the user to be nil 
    no_user false 
    end 

    # The transient variable for_user can now be used to create the 
    # associations for this factory 
    widget { Factory.create(:widget, :user => with_user) } 
    supplier { Factory.create(:supplier, :user => with_user) } 

    name 'part' 
end 

này sau đó có thể được sử dụng trong các cách sau:

# use the default user 
part = Factory.create :part 
part.widget.user.should == part.supplier.user 

# use a custom created user 
user = Factory.create :user, :name => 'Custom user' 
part = Factory.create :part, for_user: user 
part.widget.user.should == user 
part.supplier.user.should == user 

# create a part without any user 
# (again this probably isn't need in your specific case, but I have 
# found it a useful pattern) 
part = Factory.create :part, no_user: true 
part.widget.user.should be_nil 
part.supplier.user.should be_nil 
Các vấn đề liên quan