I’m using Rails 4.2.3 with FactoryGirl. I have this factory for my users
FactoryGirl.define do
…
factory :user do
after(:build) do |user, vars|
print "in main user after build.\n"
def user.publish
# and here you can stub method response if you need
end
end
…
trait :with_callbacks do
after(:build) do |user, vars|
print "after build my user\n"
end
…
end
I wanted to override my base “after(:build)” method, so I created the trait “with_callbacks.” But when I call my factory with my traits
create(:user, :my_user)
It seems like both “after(:build)” methods are getting called based on the output …
after build my user
in main user after build.
Is there a way to rig things so that I can override the base factory’s “after(:build)” method?
CodePudding user response:
You need to define another factory inside your :user
factory:
factory :user do
after(:build) do |user, vars|
print "in main user after build.\n"
def user.publish; end
end
factory :user_with_callback do
after(:build) do |user, vars|
print "after build my user\n"
end
end
end
build(:user)
# output
# => in main user after build
build(:user_with_callback)
# output
# => in main user after build
# => after build my user
CodePudding user response:
Not sure what you're trying to do, but another option would be to use a transient variable (called ignore
in FactoryBot versions < 5.0) to control the behavior, which can be overwritten in a trait.
Something like:
transient do # use `ignore` in factory bot < 5.0
with_callback_behavior { false }
end
after(:build) do |user, vars|
if vars.with_callback_behavior
puts "behavior for trait after build."
else
puts "behavior for main main after build."
end
end
trait :with_callbacks do
with_callback_behavior { true }
end
Of course, this means that
build :user, :with_callbacks
#=> "behavior for trait after build."
is the same as
build :user, with_callback_behavior: true
#=> "behavior for trait after build."