Factory Girl and has_one
Asked Answered
D

2

6

Here's my models :

Class Audition
  belongs_to :video
end

Class Video
  has_one :audition
end

and my factories :

Factory.define :video do |v|
  v.filename  {Sham.filename}
  v.video_url {Sham.url}
end

Factory.define :audition do |a|
  a.video     {|a| a.association(:video)}
  a.label     {Sham.label}
end

How could I create a video factory that have an audition,

I mean, be able to :

v = Factory.create(:video)
v.audition # I'd like this to be not nil !

Because I have an observer on my video that try to access the audition from the video object

I tried several things but I always end with a stack level too deep or audition nil.

Do you have an idea ?

Thanks, Mike

Dahl answered 10/2, 2010 at 16:44 Comment(0)
W
7

If that's the case I would add the association into the other factory:

Factory.define :video do |v|
  v.filename                        {Sham.filename}
  v.video_url                       {Sham.url}
  v.audition                        {|v| v.association(:audition)}
end

Then you can do

v = Factory(:video) # This will now have an audition
a = v.audition # This should not be nil

and

a = Factory(:audition) # An audition without a video, if that's possible?

You can also override any association as needed when you create the factory in your tests, i.e:

v = Factory(:video, :audition => Factory(:audition))
v = Factory(:video, :audition => nil)

Hope what I've said makes sense and is true lol. Let us know how you get on.

Wattle answered 10/2, 2010 at 20:53 Comment(3)
P.s. I think you get a stack level too deep if you some how tell both models that have an association with the other one.Wattle
hmm that's exactly the problem but I was hoping with some conditional magic I could include it in both :-) Your reply totally make sense, Thanks,Dahl
After being stuck with trying to put a factory girl association in both sides of the association I finally gave up on it. And just put the association inside the "slave" model. In my specs when I need to create a "master" model, I still use the "slave" factory. For example: Factory.create(:slave).master.Cajuput
F
0

In 2020 the answer is to use traits with after create actions on one of the factories, e.g.

    trait :with_audition do
      after :create do |video|
        create(:audition, video: video)
      end
    end
Fondafondant answered 19/8, 2020 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.