I've been trying now for hours to get factorygirl to create two factories - one for users, one for organizations.
But I don't seem to understand how I can reflect a 'has_and_belongs_to_many' relationship in factories, as soon as I try to create an organization and associate it with an admin user, I run into various error messages (depending on the approach I use). My model seems to be working fine, my seed file populates the dev DB and all the associations are created.
Right now my files look like this:
user factory
FactoryGirl.define do
factory :user do
email '[email protected]'
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
in my specs I test 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 are failing, here are 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 as always very much appreciated!
Update
In theory the same thing that works for assigning roles to the user should work for assigning an admin to the organization. But if I change organizations.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 following error (I do have gem shoulda installed):
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)>'
Looks like you are not assigning users
correctly and not creating the :admin
user properly. For this to work, you need to assign an array of users to organization.users
. And, you need to populate that array with a User
instance (this assumes you have a User
factory named :admin
).
factory :organization do
name "example"
website "www.aquarterit.com"
after(:create) {|organization| organization.users = [create(:admin)]}
end
I do it this way, questions and tests have a HABTM relationship so:
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
Now I can create a question with HABTM to the Test model:
let(:test) { FactoryGirl.create :test, user: user }
let(:question_test_1) { FactoryGirl.create :question_with_test, user: user, test: test }
The question_tests factory is very basic:
FactoryGirl.define do
factory :question_tests, class: 'QuestionTest' do
question
test
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With