Ruby on rails 3 工厂女孩,依赖工厂 更新

Ruby on rails 3 工厂女孩,依赖工厂 更新,ruby-on-rails-3,factory-bot,minitest,Ruby On Rails 3,Factory Bot,Minitest,我又开始使用固定装置了。IMOP,固定装置远比工厂好;更容易使用,更容易编写,更容易理解(没有魔力)。我的建议:将您的测试库限制在最基本的范围内(请听DHH)…使用带有夹具的minitest 原职 在我的应用程序中,一个地区有许多学校,一个学校有许多用途,一个用户有许多帐户,一个帐户有一个角色。为了创建完整的测试工厂,我需要创建一个跨工厂的用户和学校。在我最近的尝试中,我遇到了一个“堆栈级别太深”的错误 我的用户_test.rb FactoryGirl.define do factor

我又开始使用固定装置了。IMOP,固定装置远比工厂好;更容易使用,更容易编写,更容易理解(没有魔力)。我的建议:将您的测试库限制在最基本的范围内(请听DHH)…使用带有夹具的minitest

原职 在我的应用程序中,一个地区有许多学校,一个学校有许多用途,一个用户有许多帐户,一个帐户有一个角色。为了创建完整的测试工厂,我需要创建一个跨工厂的用户和学校。在我最近的尝试中,我遇到了一个“堆栈级别太深”的错误

我的用户_test.rb

 FactoryGirl.define do

   factory :district do
     name "Seattle"
   end

   factory :school do
     association :primarycontact, factory: :user # expecting this to attach the user_id from factory :user as :primary contact_id in the school model
     association :district, factory: :district # expecting this to attach the :district_id from the :district factory as :district_id in the school model
     name "Test School"
   end

   factory :user do, aliases: [:primarycontact]
     email "adam@example.com"
     name "Who What"
     username "wwhat"
     password "123456"
     password_confirmation { |u| u.password }
     association :school, factory: :school # expecting this to create :school_id in the users model, using the :school factory
   end

   factory :role do
     name "student"
   end

   factory :account do
     association :user, factory: :user
     association :role, factory: :role
   end

 end
因此,我正在尝试创建(:account).,我希望创建一个帐户,与上面工厂中的用户和角色以及与学区关联的学校关联的用户一起创建。这对我不起作用。在失败的测试中,我得到了一个“堆栈级别太深”的错误。而且,我相信我的before each DatabaseCleaner.clean是在每个新工厂之前清除测试数据库

调用这些工厂的测试是:

describe "User integration" do

  def log_em_in
    visit login_path
    fill_in('Username', :with => "wwhat")
    fill_in('Password', :with => "123456")
    click_button('Log In')
  end

  it "tests log in" do
    user = FactoryGirl.create(:account)
    log_em_in
    current_path.should == new_user_path
  end

end

如何改进此代码以正确嵌套工厂并获得当前用户以继续测试

模型 school.rb

  belongs_to :district
  belongs_to :primarycontact, :class_name => "User"
  has_many :users, :dependent => :destroy
user.rb

  belongs_to :school
  has_many :accounts, :dependent => :destroy
district.rb

  has_many :schools
account.rb

  belongs_to :role
  belongs_to :user
role.rb

  has_many :accounts
  has_many :users, :through => :accounts

您的基本问题是,您的
用户
工厂和
学校
工厂之间存在循环依赖关系,这是由于您在创建学校时创建了
主要联系人
(用户),然后该用户创建了学校,依此类推

您可以通过更改在
用户
工厂内定义
学校
关联的方式来解决此问题。不过,在这样做之前,我建议作为一般规则,使用速记符号来表示关联。因此,请将其替换为:

factory :account do
  association :user, factory: :user
  association :role, factory: :role
end
为此:

factory :account do
  user
  role
end
使用此简化,以下工厂将执行您想要的操作,而不会生成任何循环依赖项:

FactoryGirl.define do

  factory :district do
    name "Seattle"
  end

  factory :school do |school|
    district
    primarycontact
    name "Test School"
    after_build do |s|
      s.primarycontact.school = s
    end
  end

  factory :user do
    email "adam@example.com"
    name "Who What"
    username "wwhat"
    password "123456"
    password_confirmation { |u| u.password }
    school
  end

  factory :primarycontact, class: "User" do
    # add any attributes you want the primarycontact user to have here
  end

  factory :role do
    name "student"
  end

  factory :account do
    user
    role
  end

end
请注意,我所做的是使用
类:“User”
选项为
primarycontact
创建一个工厂。与
用户
工厂不同,默认情况下,此工厂不创建
学校
,从而避免了循环依赖

然后在
school
工厂中,我使用
after\u build
回调将学校本身分配给
school
上的
primarycontact
关联,而不是创建一个新学校(这导致了工厂中的问题)


希望这是有道理的。请注意,在较新版本的factory\u girl中,回调语法已更改,有关详细信息,请参阅。

您写道,一所学校的
有许多
用户,但在您的工厂中,它似乎只有一个用户,如
primarycontact
。你能发布这些型号的代码吗(只有关联信息的第一行)?p.s.只要看一下你的工厂代码,问题似乎很明显,你的
学校
工厂和你的
用户
工厂之间存在循环依赖关系:一个
学校
有一个
主要联系人
,它是使用
用户
工厂创建的,但是
用户
也有一个学校,它是使用
学校
工厂定义的。学校属于:primarycontact,:class\u name=>“user”,有许多:用户。不确定我为什么这样做(旧代码)…我想我会修改它,在用户模型中使用布尔值定义主要联系人。我会在上面添加我现有的模型代码…谢谢你似乎对我的循环依赖性是正确的。我从学校模型中删除了primarycontact的验证,从我的工厂中删除了primarycontact…并删除了测试记录和用户登录。我将学校模型设置为有多个用户,但也属于:primarycontact,:class=>“user”,这样只有一个用户可以成为主要用户。我可以在用户模型中使用一个布尔值和一些验证来实现这一点……我想在我最初设置它时,我认为这种方法更容易。我现有的方法是否存在问题(除了我在测试中遇到的问题外)?这是否意味着我需要重新定义在:primarycontact中定义的所有内容:user?(电邮)adam@example.com“等等)我最近放弃了工厂,回到了固定装置。我喜欢!我再也不会使用工厂了。
FactoryGirl.define do

  factory :district do
    name "Seattle"
  end

  factory :school do |school|
    district
    primarycontact
    name "Test School"
    after_build do |s|
      s.primarycontact.school = s
    end
  end

  factory :user do
    email "adam@example.com"
    name "Who What"
    username "wwhat"
    password "123456"
    password_confirmation { |u| u.password }
    school
  end

  factory :primarycontact, class: "User" do
    # add any attributes you want the primarycontact user to have here
  end

  factory :role do
    name "student"
  end

  factory :account do
    user
    role
  end

end