如何使用工厂女孩使用has_many创建关联列表,并在创建时进行验证 [英] How to user factory girl to create associated lists with a has_many with a validation that requires it on create
问题描述
在Rails应用程序中,给定三个模型User,Article和Reviewer,它们具有以下关系和验证:
In a Rails application, given three models User, Article and Reviewer with the following relationships and validations:
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
以及以下使用较新DSL的工厂:
And the following factories using the newer DSL:
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
创建文章的工厂不起作用,因为在创建审阅者之前验证失败:
The factory to create the article doesn't work because the validation fails before the reviewers are created:
> FactoryGirl.create(:article)
ActiveRecord::RecordInvalid: Validation failed: article must have at least one reviewer.
我付出了比我想承认的更大的尝试来克服这个障碍,但是我被困住了!我曾经想到的一个想法是创建这样的审阅者:
I have made more attempts than I would like to admit trying to overcome this hurdle, but I am stuck! One idea I had was to create the reviewers like this:
factory :article do
body "This is the article content"
title "This is the title"
user
reviewers {|a| [FactoryGirl.create(:reviewer, article: a)] }
end
,但是在这种情况下,"a"不是实例.因此,这也不起作用,就像以前一样.
but in this context, the "a" is not the instance. So that doesn't work either, like it used to.
推荐答案
我将此问题重新发布到了Factory Girl github页面上,并设法解决了这个问题:
I reposted this over on the Factory Girl github page as an issue and worked my way around to the answer:
before_create do |article|
article.reviewers << FactoryGirl.build(:reviewer, article: article)
end
键是在before_create中完成的,因此尚未触发验证,并确保将新创建的审阅者推送到正在创建的实例的审阅列表中.感谢Unixmonkey的响应并让我不断尝试新事物:)
The key was doing it in a before_create, so the validations haven't fired yet, and making sure to push the newly created reviewer into the list of reviews on the instance being created. Thanks to Unixmonkey for responding and keeping me trying new things :)
https://github.com/thoughtbot/factory_girl/issues/369# issuecomment-5490908
这篇关于如何使用工厂女孩使用has_many创建关联列表,并在创建时进行验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!