setting instance variables in factorygirl
Asked Answered
P

2

7

Say I have a model like

class Vehicle < ActiveRecore::Base

  after_initialize :set_ivars

  def set_ivars
    @my_ivar = true
  end
end

and somewhere else in my code I do something like @vehicle.instance_variable_set(:@my_ivar, false)

and then use this ivar to determine what validations get run.

How do I pass this Ivar into FactoryGirl?

 FactoryGirl.define do
   factory :vehicle do
      association1
      association2
   end
 end

How do I encode an ivar_set into the above, after create, before save? How do I pass it into a FactoryGirl.create()?

Plea answered 14/2, 2014 at 9:48 Comment(2)
Is there any particular reason why you're not defining setter?Nestor
because it was late when I was implementing this and my brain was on strike xDPlea
N
7
FactoryGirl.define do
   factory :vehicle do
      association1
      association2
      ignore do
        my_ivar true
      end

      after(:build) do |model, evaluator|
        model.instance_variable_set(:@my_ivar, evaluator.my_ivar)
      end
    end
 end

 FactoryGirl.create(:vehicle).my_ivar                    #=> true
 FactoryGirl.create(:vehicle, my_ivar: false).my_ivar    #=> false
Nestor answered 14/2, 2014 at 9:53 Comment(1)
Could you describe a bit more what ignore does? Maybe just code is to less for many of us.Pilgrimage
Q
0

A bit late answer, nonetheless I had the need to setup an instance variable on a model. And since the above answer didn't work for the latest version of factory bot I did a bit of research and found out that the following approach works for me:

 FactoryGirl.define do
   factory :vehicle do
     association1
     association2
   end
   transient do
     my_ivar { true }
   end

   after(:build) do |model, evaluator|
     model.instance_variable_set(:@my_ivar, evaluator.my_ivar)
   end
 end

It's almost identical to the above answer but instead of ignore it uses transient keyword, I assume this is an in-place replacement for ignore.

What it does is that it allows to define a variable you can pass on to the factory but that doesn't end up being set on the resulting object. That in turn gives you an opportunity to do logic based upon it. Like we do in this example (albeit a simple one) where we set an instance variable based on the provided transient variable.

Note that the transient variable is set and available in the evaluator variable.


References:

Quilt answered 8/3, 2022 at 11:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.