Reputation: 10368
This question probably has been asked many times. Here is our version. There are user and user_level model in our rails 3.1 app. A user has_many user_levels.
class User < ActiveRecord::Base
has_many :user_levels
accepts_nested_attributes_for :user_levels, :allow_destroy => true
validates_presence_of :user_levels
end
class UserLevel < ActiveRecord::Base
belongs_to :user
validates :position, :presence => true
end
Here is what we have in FactoryGirl 3.3:
FactoryGirl.define do
factory :user_level do
position "admin"
user
end
factory :user do
name "Test User"
login 'testuser'
password "password1"
factory :user_with_levels do
#user_levels
after(:create) do |user|
FactoryGirl(:user_level, :user => user)
end
end
end
end
u = FactoryGirl.build(:user_with_levels) or u = FactoryGirl.create(:user_with_levels)
are used in our rspec. The after create callback did not work and there are errors saying Validation failed: User levels can't be blank
. What's wrong with the callback above? Thanks so much.
Upvotes: 0
Views: 1263
Reputation: 10368
Here is a solution that works. It is based on the following post by Tim Riley: http://icelab.com.au/articles/factorygirl-and-has-many-associations/
FactoryGirl.define do
factory :user_level do
position "admin"
user
end
factory :user do
name "Test User"
login 'testuser'
password "password1"
#user_levels
after(:build) do |user|
user.user_levels << FactoryGirl.build(:user_level, :user => user)
end
end
end
The problem (user level can't be blank) is because there is no user level when user is saved. User level needs to be built along with the user.
Upvotes: 4
Reputation: 2167
I think it's because validations on your nested models fire whenever create
tries to save
a user
factory. Have you tried using an after(:build)
callback instead?
Upvotes: 1