views:

29

answers:

1

Is there a way in factory_girl to specify a random instance that an association should point to? For example, I have a Like object which belongs_to one User and one SocialUnit. I want the factory for Like to pick a random existing User and a random SocialUnit to like, instead of just generating a new one. The below snippet sort of works:

Factory.define :like do |f|
  if User.all.count > 0
    f.user User.all.sort_by{ rand }.first
  else
    f.association :user
  end
end

It indeed picks a random user, but it seems like the random user only gets picked once, because running this

def create_hauls
  5.times do |i|
    Factory(:haul)
  end
end

creates a bunch of likes all with the same user. I guess that makes sense... the factory gets defined once, and then reused a bunch of times.

I could use a sequence to force randomness; is there a way to define it within the factory definition, or is the sequence the best way to do it?

Thanks.

+1  A: 

You want to use a lazy attribute instead of defining the user when the factory is defined. This will define the user each time the factory is used instead.

f.user { (User.all.count > 0 ? User.all.sort_by{ rand }.first : Factory.create(:user)) }

jdl
ah, thanks. i had implemented a solution with a sequence (replacing `if User.all.count > 0` in my snippet with `Factory.next(:random_user)`, but looking back, that was wrong because it was still going to check whether `User.all.count > 0` only once. Thanks for the help!
unsorted