Factory Girl and has_many / has_many :through associations

If you want to create has_many and has_many through associations in factory_girl as I once did, you will need to put it inside square brackets:

Factory.define :user do |user|
  user.name "My Name"
  user.groups {|groups| [groups.association(:group)]}
end

This will ensure that user.groups is not overriden by a single Group object, but by an array with a Group inside.

~ by dante regis on November 19, 2008.

7 Responses to “Factory Girl and has_many / has_many :through associations”

  1. If it wasn’t for excellent people like you – who find an answer to an annoying problem like this and then publish it to the world – people like me would spend hours hitting our heads against a brick wall. I salute you!

    Just started using Factory Girl and it looks really useful but, unless I’m being thick, I couldn’t find this in the rdoc.

  2. I try your suggestion but…
    All groups end up with “user_id = nil”
    Using factory_girl 1.2.0

  3. can you tell us how your relationships are defined in the models so we can help you better?

  4. I’m sure you couldn’t, and that’s not your fault. It’s not there. I found it on a blog, but since I posted a few days after reading it, I could not remember the source, for what I am sorry.

  5. I simply tried the suggestion making
    class User
    has_many :posts
    class Post
    belongs_to :user

    In the code above all groups end up with “user_id = nil”. Actually the factory creates the posts and the users. And the result is many unrelated posts and users.

    Can we consider it a bug or missing feature of factory girl?
    The one to many definition does not work:
    user.groups {|groups| [groups.association(:group)]}

  6. Nice tip. I respect you.

  7. You are trying to write complicated factories? Maybe you need to add
    helper methods to your factories to keep it clean. Here is how:
    http://conceptspace.wikidot.com/blog:39

    This allows you to define complicated belongs_to and has_many
    scenarios neatly. For example:

    Factory.define :child do |f|

    class << f
    #do whatever you can do in a normal class definition
    def default_parent
    @default_parent ||= Factory(:parent)
    end
    end

    f.sequence(:name) {|n| "Child#{n}"}
    f.parent_id { f.default_parent.id }
    end

Leave a Reply