使用Factory Girl创建HABTM关联

7

我已经尝试了几个小时,想让FactoryGirl创建两个工厂 - 一个用于用户,一个用于组织。

但是,我似乎不明白如何在工厂中反映出“has_and_belongs_to_many”关系。只要我尝试创建一个组织并将其与管理员用户关联起来,我就会遇到各种错误消息(取决于我使用的方法)。我的模型似乎运行良好,我的种子文件填充了dev数据库,并创建了所有的关联。

现在我的文件看起来像这样:

用户工厂

FactoryGirl.define do

  factory :user do
    email 'example@example.com'
    password 'password'
    password_confirmation 'password'
    after(:create) {|user| user.add_role(:user)}

    factory :owner do
      after(:create) {|user| user.add_role(:owner)}
    end

    factory :admin do
      after(:create) {|user| user.add_role(:admin)}
    end

    factory :superadmin do
      after(:create) {|user| user.add_role(:superadmin)}
    end
  end
end

Organization factory

FactoryGirl.define do

  factory :organization do |f|
    f.name "example"
    f.website "www.aquarterit.com"
    f.association :users, :factory => :admin
  end
end

在我的规格中,我测试了这个:

describe Organization do


  it "has a valid factory" do
    FactoryGirl.create(:organization).should be_valid
  end

  it "is invalid without a name" do
    FactoryGirl.build(:organization, name: nil).should_not be_valid
  end

  it "is associated with at least one admin user" do
    FactoryGirl.create(:organization)
    it { should have_and_belong_to_many(:users)}
  end

end

三个测试都失败了,以下是错误信息:

1) Organization has a valid factory
     Failure/Error: FactoryGirl.create(:organization).should be_valid
     NoMethodError:
       undefined method `each' for #<User:0x007fadbefda688>
     # ./spec/models/organization_spec.rb:7:in `block (2 levels) in <top (required)>'

  2) Organization is invalid without a name
     Failure/Error: FactoryGirl.build(:organization, name: nil).should_not be_valid
     NoMethodError:
       undefined method `each' for #<User:0x007fadc29406c0>
     # ./spec/models/organization_spec.rb:11:in `block (2 levels) in <top (required)>'

  3) Organization is associated with at least one admin user
     Failure/Error: organization = FactoryGirl.create(:organization)
     NoMethodError:
       undefined method `each' for #<User:0x007fadc2a3bf20>
     # ./spec/models/organization_spec.rb:15:in `block (2 levels) in <top (required)>'

任何帮助都非常感激!
更新
理论上,给用户分配角色的方法也适用于将管理员分配给组织。但是,如果我更改organizations.rb为:
FactoryGirl.define do

  factory :organization do
    name "example"
    website "www.aquarterit.com"
    after(:create) {|organization| organization.add_user(:admin)}
  end
end

我遇到了以下错误(我确实已经安装了shoulda gem):
1) Organization is associated with at least one admin user
     Failure/Error: it { should have_and_belong_to_many(:users)}
     NoMethodError:
       undefined method `it' for #<RSpec::Core::ExampleGroup::Nested_1:0x007ff2395f9000>
     # ./spec/models/organization_spec.rb:16:in `block (2 levels) in <top (required)>'

我认为这篇文章回答了你的问题:https://dev59.com/vnM_5IYBdhLWcg3wMgAF - Nikolai Manek
谢谢 - 我之前找到过那个,但据我所知它没有使用最新的语法;现在factorygirl建议使用after(:create)来添加关联,是吗?已更新原问题以包括修改后的organization工厂。 - Thomas Kuhlmann
2个回答

18

看起来你没有正确地分配users并且没有正确地创建:admin用户。为了使其正常工作,你需要将一个用户数组分配给organization.users。而且,你需要用User实例填充该数组(这假设你有一个名为:adminUser工厂)。

factory :organization do
  name "example"
  website "www.aquarterit.com"
  after(:create) {|organization| organization.users = [create(:admin)]}
end

1

我是这样做的,问题和测试之间存在HABTM关系:

FactoryGirl.define do
  factory :question do
   question  'Some stupid question'
   user nil
   factory :question_with_test do
     # factory_girl's dynamic attributes, ignore it and pass it to evaluator
     transient do
       test nil
     end

     after(:create) do |question, evaluator|
       create(:question_tests, question: question, test: evaluator.test)
     end
   end
  end
end

现在我可以使用HABTM为Test模型创建一个问题:
let(:test)             { FactoryGirl.create :test, user: user }
let(:question_test_1)  { FactoryGirl.create :question_with_test, user: user, test: test }

question_tests工厂非常基础:

FactoryGirl.define do
  factory :question_tests, class: 'QuestionTest' do
    question
    test
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接