Home > Enterprise >  In Rails 4 and FactoryGirl, how do I override the base factory's "after(:build)" meth
In Rails 4 and FactoryGirl, how do I override the base factory's "after(:build)" meth

Time:06-21

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."
  • Related