Using a factory girl to create a HABTM association

I've been trying for hours to get a breeder to create two factories - one for users, one for organizations.

But I don’t seem to understand how I can reflect the has_and_belongs_to_many relationships in the factories, as soon as I try to create an organization and associate it with the administrator user, I came across various error messages (depending on the approach I use). My model seems to be working fine, my seed file populates Dev DB and all associations are created.

My files now look like this:

factory user

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 

Factory Organization

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

in my specs I check this:

 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 

all three tests do not work, here is the error message:

 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)>' 

Any help is always greatly appreciated!

Update

Theoretically, the same thing that works for assigning roles to a user should work for appointing an administrator of an organization. But if I change organization.rb to

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

I get the following error (I have gem shoulda):

 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)>' 
+6
source share
2 answers

It looks like you did not correctly assign users , and you did not create the user correctly :admin . To do this, you need to assign an array of users to organization.users . And you need to populate this array with a User instance (assuming you have a User factory named :admin ).

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

I do it this way, questions and tests are related to HABTM, therefore:

 FactoryGirl.define do factory :question do question 'Some stupid question' user nil factory :question_with_test do # factory_girl 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 

Now I can create a question with HABTM for the test model:

 let(:test) { FactoryGirl.create :test, user: user } let(:question_test_1) { FactoryGirl.create :question_with_test, user: user, test: test } 

Question_tests factory is very simple:

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

All Articles