如何用户工厂女孩创建带有has_many的关联列表,该列表具有在创建时需要它的验证



在 Rails 应用程序中,给定三个模型 User、Article 和 Reviewer,具有以下关系和验证:

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的工厂:

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
创建

文章的工厂不起作用,因为在创建审阅者之前验证失败:

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

为了克服这个障碍,我做了比我愿意承认的更多的尝试,但我被困住了!我的一个想法是像这样创建审阅者:

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

但在这种情况下,"A"不是实例。所以这也行不通,就像以前一样。

我将其作为问题重新发布在Factory Girl github页面上,并努力找到答案:

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

关键是在before_create中执行此操作,因此尚未触发验证,并确保将新创建的审阅者推送到正在创建的实例上的审阅列表中。 感谢Unixmonkey的回应,让我尝试新事物:)

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

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

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

新语法为:

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

最新更新