How do I save a local variable within a factory
Asked Answered
D

3

15

I have this example

FactoryGirl.define do
  @site = FactoryGirl.create(:my_site)
  factory :user do
    email               { Faker::Internet.email }
    first_name          { Faker::Name.first_name }
    last_name           { Faker::Name.last_name }
    password            { 'TarXlrOPfaokNOzls2U8' }
    active_directory    { '0' }
    companies           { [FactoryGirl.create(:company, site: @site)] }
    sites               { [@site] }
  end
end

Is there a way to achieve this with a let or something...

FactoryGirl.define do
  factory :user do
    email               { Faker::Internet.email }
    first_name          { Faker::Name.first_name }
    last_name           { Faker::Name.last_name }
    password            { 'TarXlrOPfaokNOzls2U8' }
    active_directory    { '0' }
    companies           { [FactoryGirl.create(:company, site: FactoryGirl.create(:my_site))] }
    sites               { [FactoryGirl.create(:my_site)] }

  end
end

This works but it creates two my_site which is a Site object but I need them to be the same...any idea on how to achieve this

Dickson answered 6/7, 2012 at 14:56 Comment(2)
what's the problem with a local variable? site = FactoryGirl.create(:my_site)Psychosomatic
your right that did workDickson
P
25

Probably the simplest is to use a local variable:

FactoryGirl.define do
  site = FactoryGirl.create(:my_site)

  factory :user do
    email               { Faker::Internet.email }
    first_name          { Faker::Name.first_name }
    last_name           { Faker::Name.last_name }
    password            { 'TarXlrOPfaokNOzls2U8' }
    active_directory    { '0' }
    companies           { [FactoryGirl.create(:company, site: site)] }
    sites               { [site] }
  end
end
Psychosomatic answered 6/7, 2012 at 15:7 Comment(1)
The problem with this is that it only creates the site variable once. if i want a variable created each time factorybot runs (like my_rand_number = Random.rand(1..10)), i would only get one random number and it would be the same number every time i create a new model instance. do you know how to get a different random number with each FactoryBot.create(:my_site) statement?Maryalice
J
6

I finally figured out a good way to do this. This question is pretty old, but I thought I'd post an answer in case other people come across this.

You can use a before(:create) callback (or before(:build) if thats your use case) to set the sites collection, and then assign the first element of the sites collection to the newly created company in the company collection.

More information about FactoryBot callbacks can be found here.

Just so readers know, I'm using the new FactoryBot class name as FactoryGirl is deprecated.

FactoryBot.define do
  factory :user do
    email               { Faker::Internet.email }
    first_name          { Faker::Name.first_name }
    last_name           { Faker::Name.last_name }
    password            { 'TarXlrOPfaokNOzls2U8' }
    active_directory    { '0' }

    before(:create) do |user|
      user.sites << FactoryBot.create(:my_site)
      user.companies << FactoryBot.create(:company, site: user.sites.first)
    end
  end
end
Jenness answered 20/4, 2018 at 14:41 Comment(0)
I
0

An easy way is defining a transient attribute. It has the extra benefit of be overridable on factory instantiation.

  transient do
    site { FactoryGirl.create(:my_site) { true } }
  end
Incandescent answered 26/6 at 13:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.