2012-05-02 9 views
18

Trong một ứng dụng Rails, được đưa ra ba mô hình dùng, Điều và phản biện với các mối quan hệ và kiểm chứng thực sau đây:Làm thế nào để sử dụng máy cô gái để tạo danh sách liên quan với một has_many với một xác nhận rằng đòi hỏi nó trên tạo

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 

và các nhà máy sau bằng cách sử dụng DSL mới hơn:

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 

nhà máy để tạo ra các bài viết không hoạt động vì sự xác nhận thất bại trước khi nhận xét được tạo ra:

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

Tôi đã nỗ lực nhiều hơn tôi muốn thừa nhận cố gắng vượt qua rào cản này, nhưng tôi bị kẹt! Một ý tưởng tôi có là tạo ra những người đánh giá như sau:

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

nhưng trong ngữ cảnh này, "a" không phải là trường hợp. Vì vậy, điều đó không hoạt động hoặc, như nó được sử dụng để.

Trả lời

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

hoặc

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

Khi tôi cố gắng này, tôi nhận được: SystemStackError: ngăn xếp mức quá sâu. Có vẻ như khi nhà máy đánh giá bị sa thải, nó không biết về bài viết, vì vậy sau đó nó cố gắng tạo thêm một bài viết khác. – Blizzo

+0

@Blizzo Bạn có thể xóa việc tạo bài viết từ nhà máy của người đánh giá hoặc sử dụng before_create. Tôi đã chỉnh sửa câu trả lời của mình để phản ánh điều đó. – Unixmonkey

+0

Tôi đưa ra ví dụ thứ hai của bạn một shot cũng như sau khi bạn thêm nó và có lỗi xác nhận: ActiveRecord :: RecordInvalid: Xác thực không thành công: bài viết phải có ít nhất một người đánh giá một lần nữa – Blizzo

22

tôi cập nhật này trên trên trang github Factory Girl như một vấn đề và làm việc theo cách của tôi xung quanh để câu trả lời:

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

Mấu chốt đã làm nó trong một before_create, do đó, các xác nhận hợp lệ vẫn chưa được kích hoạt và đảm bảo đẩy người đánh giá mới được tạo vào danh sách các đánh giá về cá thể đang được tạo. Nhờ Unixmonkey để ứng phó và giữ tôi cố gắng những điều mới lạ :)

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

+0

Tôi đã có một vấn đề tương tự và điều này giải quyết nó. Cảm ơn! – ryanpitts1

1

Cú pháp mới là:

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