views:

102

answers:

1

I have 2 Models:

# user.rb
class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy
end

# profile.rb
class Profile < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :user
end

# user_factory.rb
Factory.define :user do |u|
  u.login "test"
  u.association :profile
end

I want to do this:

@user = Factory(:user)
=> #<User id: 88,....>
@user.profile
=> #<Profile id:123, user_id:88, ......>

@user = Factory.build(:user)
=> #<User id: nil,....>
@user.profile
=> #<Profile id:nil, user_id:nil, ......>

But this doesn't work! It tells me that my profile model isn't correct because there is no user! (it saves the profile before the user, so there is no user_id...)

How can I fix this? Tried everything.. :( And I need to call Factory.create(:user)...

UPDATE:

Fixed it with: This fixes the problem, but then Factory.build(:user) saves the user... Dont know why???

Factory.define :user do |u|
  u.login "test"
  u.after_build { |a| Factory(:profile, :user => a)}

  # u.after_build { |a| Factory.build(:profile, :user => a)}
  # raises the validate_presence_of :user - error message again...
end

class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy, :inverse_of => :user
end

This should not save the user, but it does!

@user = Factory.build(:user)
=> #<User id: 88,....>
@user.profile
=> #<Profile id:123, user_id:88, ......>

UPDATE

Fixed this issues - working now with:

# user_factory.rb
Factory.define :user do |u|
  u.profile { Factory.build(:profile)}
end

# user.rb
class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy, :inverse_of => :user
end

# profile.rb
class Profile < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :user
end
+1  A: 

Fix it that way (as explained in this post)

Factory.define :user do |u|
  u.login "test"
  u.profile { |p| p.association(:profile) }
end

What you can do as well (as a user don't need a profile to exist (there's no validation on it) is to do a two steps construction

Factory.define :user do |u|
  u.login "test"
end

and then

profile = Factory :profile
user = Factory :user, :profile => profile

I guess in that case you even just need one step, create the user in the profile factory and do

profile = Factory :profile
@user = profile.user

That seems the right way to do it, isn't it?

Update

(according to your comment) To avoid saving the profile use Factory.build to only build it.

Factory.define :user do |u|
  u.login "test"
  u.after_build { |a| Factory(:profile, :user => a)}    
end
mb14
I tried that before and it didn't work, because the Profile becomes saved before the user... And so the validates_presence_of :user-validation won't accept saving... Fixed it with my solution above!
Lichtamberg
Ok, didn't see you answered your own post. That's weird anyway. We use factory girl a lot (where I work) and I've never seen this problem.
mb14
Ok... But my solution didn't work out in the end.. The User gets saved, even if i call Factoy.build(:user)... Dont know why... aaarghh Updated my post...
Lichtamberg
I'm confused... all works with "u.profile { Factory.build(:profile)}", but not with your suggestion "u.profile { |p| p.association(:profile) }"... Crazy ^^
Lichtamberg
When you change your answer to my fix above, i will mark your answer as accepted... Thanks!
Lichtamberg