Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

exSnake's avatar

Factory FirstOrCreate

Hi guys, i want to make a setUp for my feature test.

Is there something like

$viewPermission = factory(\App\Permission::class)->firstOrCreate(['name' => 'view_user']);

I'm asking this because sometime this permission could already exist and my test would fail, also in my test i don't wan't to specify label and guard_name and others unnecessary parameters.

I have migration that create Permission but sometime this permission could be missing because i've created new models and forgot to add each ew permission into the migration (is this the right way?).

0 likes
5 replies
Alyve's avatar

Hello,

In your test, you can choose to use RefreshDatabase to reset all your database or DatabaseTransactions to remove everything you added in your test.

I think you are doing some test with your Permission class which does not delete what you added previously, that's why you have the Permission… or not.

When you run php artisan test, it's not running sequentially, if a previous test is executed before your current test (with the firstOrCreate), the Permission already exists, then you can't create it.

I hope it helps you.

1 like
exSnake's avatar

I've migration who create some permissions, that's why i wan't to use firstOrCreate, if doesn't exist he should create it using his factory, i thought there was a way to do it through factory itself

tykus's avatar
tykus
Best Answer
Level 104

There is no firstOrCreate (or equivalent) on the FactoryBuilder class, but it is macroable, so you can implement that behaviour yourself.

Otherwise in your test setup, you could either (i) wrap the factory function call in a try/catch:

try {
	$viewPermission = factory(\App\Permission::class)->create(['name' => 'view_user']);
} catch (QueryException $e) {
	$viewPermission = \App\Permission::class)->where('name', 'view_user')->first;
}

or (ii) use the Model itself

$viewPermission = \App\Permission::firstOrCreate(factory(\App\Permission::class)->raw());
2 likes
exSnake's avatar

But with the Model i cannot pass the factory because he will create different model everytime, even if i specify the name other properties will be different. Probably i will go with the first

tykus's avatar

True. I don't have sight of your PermissionFactory, so I don't know if there is more attributes than the name!

If you take that second example again, you can use firstOrCreate on the name attribute like this:

$viewPermission = \App\Permission::firstOrCreate(
	$attributes = ['name' => 'view_user'],
	factory(\App\Permission::class)->raw($attributes)
);
2 likes

Please or to participate in this conversation.