37

Let’s say you have the following mongoid documents:

class User
    include Mongoid::Document
    embeds_one :name
end

class UserName
    include Mongoid::Document
    field :first
    field :last_initial

    embedded_in :user
end

How do you create a factory girl factory which initializes the embedded first name and last initial? Also how would you do it with an embeds_many relationship?

2 Answers 2

63

I was also looking for this one and as I was researching I've stumbled on a lot of code and did pieced them all together (I wish there were better documents though) but here's my part of the code. Address is a 1..1 relationship and Phones is a 1..n relationship to events.

  factory :event do
    title     'Example Event'

    address  { FactoryGirl.build(:address) }
    phones    { [FactoryGirl.build(:phone1), FactoryGirl.build(:phone2)] }
  end

  factory :address do
    place     'foobar tower'
    street    'foobar st.'
    city      'foobar city'
  end

  factory :phone1, :class => :phone do
    code      '432'
    number    '1234567890'
  end

  factory :phone2, :class => :phone do
    code      '432'
    number    '0987654321'
  end

(And sorry if I can't provide my links, they were kinda messed up)

2
  • Thanks for this. I just wasted hours tracking down this problem. Apr 28, 2013 at 1:28
  • 1
    Note that the phones attribute is an array (the FactoryGirl calls are surrounded by []). You do not need more than one :phone but it has to be an array if the relation is an embeds_many. That detail cost me about 4 hours!
    – SteveO7
    Jul 31, 2013 at 18:11
6

Here is a solution that allows you to dynamically define the number of embedded objects:

FactoryGirl.define do
  factory :profile do
    name 'John Doe'
    email '[email protected]'
    user

    factory :profile_with_notes do
      ignore do
        notes_count 2
      end

      after(:build) do |profile, evaluator|
        evaluator.notes_count.times do
          profile.notes.build(FactoryGirl.attributes_for(:note))
        end
      end
    end
  end
end

This allows you to call FactoryGirl.create(:profile_with_notes) and get two embedded notes, or call FactoryGirl.create(:profile_with_notes, notes_count: 5) and get five embedded notes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.