Summer Sale! All accounts are 50% off this week.

Vishal_kariya's avatar

How to disable Factory Callbacks

Hi, I have defined Model Factory Callbacks afterMaking and afterCreating. But, for some factory create() or make() calls I do not want the callbacks to be executred. Is there any way? I am using Laravel 8.X version. Thanks for the help!

0 likes
2 replies
cwhite's avatar

There's a couple of things you can do:

  1. Consider using a state instead of a callback.
  2. If you must use a callback, you can add a method to your factory that sets a static variable, then you can check for that static variable in your callbacks.

Example 2:

class FooFactory extends Factory
{
    protected $model = Foo::class;

    protected static bool $shouldExecuteCallbacks = true;

    // ...

    public function configure(): Factory
    {
        if (! static::$shouldExecuteCallbacks) {
            return $this;
        }
        
        return $this->afterMaking(function (Foo $foo) {
            //
        });
    }


    public function disableCallbacks(): Factory
    {
        static::$shouldExecuteCallbacks = false;

        return $this;
    }
}

// then use like
Foo::factory()->disableCallbacks()->create();
Vishal_kariya's avatar

I think if managed via static variable, for subsequent call we will need to reset it. I prepared small trait DisableCallbacks like below

use Illuminate\Support\Collection;

trait DisableCallbacks
{

    /**
     * set callbacks to empty
     *
     * @return $this
     */
    public function withoutCallbacks()
    {
        $this->withoutAfterCreating();
        $this->withoutAfterMaking();

        return $this;
    }

    /**
     * set afterCreating to empty
     *
     * @return $this
     */
    public function withoutAfterCreating()
    {
        $this->afterCreating = new Collection;

        return $this;
    }

    /**
     * set afterMaking to empty
     *
     * @return $this
     */
    public function withoutAfterMaking()
    {
        $this->afterMaking = new Collection;

        return $this;
    }
}
// then use like
Foo::factory()->withoutCallbacks()->create();
Foo::factory()->withoutAfterCreating()->create();
Foo::factory()->withoutAfterMaking()->create();
1 like

Please or to participate in this conversation.