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)]}

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.

15 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.

    • 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.

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

  3. 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)]}

  4. Nice tip. I respect you.

  5. You are trying to write complicated factories? Maybe you need to add
    helper methods to your factories to keep it clean. Here is how:

    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)

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

  6. thanks, that really helps a lot

  7. Thanks! This issue cost me about an hour today. The docs still only have the rarer has_one/belongs_to examples.

  8. […] Dante Regis has written about this before but I found it sufficiently sufficiently frustrating that I thought I’d document it as well. […]

  9. Whoa! This issue still exists since I couldn’t get things working before I read your tip.


  10. Ditto that, burnt a day on this. Finally a solution. 🙂
    In your original post your wrote that you “once” used factory girl for has_many. What do you use now?

  11. If you then wanted to build a user associated with a specific group in your test suite, do this:

    build(:user, :groups => [ build(:group, :group_name => ‘Rails Developers’) ])

    ‘group_name’ and ‘Rails Developers’ are just arbitrarily chosen. But hope the correct syntax helps.

  12. […] only source of help I found for this can be found at Factory Girl and has_many / has_many :through associations by Dante […]

  13. Wonderful website. Plenty of helpful information here. I am
    sending it to several friends ans also sharing in delicious.

    And obviously, thank you on your sweat!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: