Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting up Embedded Mongoid Models with Factory_Girl

So I'm playing with Mongoid, Rspec and Factory_Girl and I had some issues with an embedded document.

I had the following models:

class Profile    
   include Mongoid::Document

   #Fields and stuff
      embeds_one :address

   validates :address, presence: true 
end

class Address    
   include Mongoid::Document

   #Fields and stuff
      embedded_in :profile 
end

So when I defined a factory like this:

FactoryGirl.define do
  factory :profile do
    #fields

    address
  end
end

I got an error like this:

Failure/Error: subject { build :profile }
     Mongoid::Errors::NoParent:

       Problem:
         Cannot persist embedded document Address without a parent document.
       Summary:
         If the document is embedded, in order to be persisted it must always have a reference to it's parent document. This is most likely cause by either calling Address.create or Address.create! without setting the parent document as an attribute.
       Resolution:
         Ensure that you've set the parent relation if instantiating the embedded document direcly, or always create new embedded documents via the parent relation.

I got it working by changing the factory to something like this:

FactoryGirl.define do
  factory :profile do
    #fields

    after(:build) do |p| 
      p.create_address(FactoryGirl.attributes_for(:address))
    end
  end
end

This works but I'm hoping there's a more native Factory_Girl way of doing this. It seems like there should be.

Thanks in advance!

like image 736
Drew Avatar asked Oct 15 '12 15:10

Drew


2 Answers

You can do it this way, too, as referenced in Factory Girl + Mongoid embedded documents in fixtures:

FactoryGirl.define do
  factory :profile do |f|
    #fields
    address { FactoryGirl.build(:address) }
  end
end
like image 134
Andrew Stott Avatar answered Sep 28 '22 16:09

Andrew Stott


Try to use build_address instead of create_address. In my opinion your factory is broken because you're trying to create an address record before profile record is persisted (created). build_* should assign all necessary attributes to the parent model and later it should be persisted along with its embedded relations.

like image 26
luacassus Avatar answered Sep 28 '22 15:09

luacassus