Reputation: 15471
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()
?
Upvotes: 7
Views: 2237
Reputation: 8998
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:
Upvotes: 0
Reputation: 44695
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
Upvotes: 7