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

Thijmen's avatar

Unique constraint in database with factory

Hello folks,

I have a unique constraint on a column in a table called users. Lets call this column 'pizza'. In my ModelFactory I defined the 'pizza' column as $faker->numberBetween(0,1000). When i create 50 users, it sometimes fails on the constraint. I want to try the factory a few times and then finish the factory.

Is this possible or do I want something completely impossible?

0 likes
4 replies
Corez64's avatar
Corez64
Best Answer
Level 37

In order to do that you would need to keep a list of the random numbers you have generated, if your new random number is in your list generate a new random number:

$uniquePizzaNumber = function() {
    static $usedNumbers = [];
    do {
        $pizza = $faker->numberBetween(0,1000);
    } while (in_array($usedNumbers, $pizza);

    return $pizza;
}

This will work so long as you call the factory only once (e.g. in a migration or using tinker) if you want to call it multiple times you will have to check the database for a conflict rather than the $usedNumbers array.

$uniquePizzaNumber = function() {
    do {
        $pizza = $faker->numberBetween(0,1000);
    } while (DB::table('pizza_table')->where('pizza', $pizza)->count());

    return $pizza;
}

As an alternative you could just make the sequential for testing, be much easier.

4 likes
veve286's avatar

$faker->unique( )->numberBetween(0,1000);

Faker object have built in special function called unique which is need to call before any others method.

7 likes
Thijmen's avatar

Thanks guys! Both options work like a charm :)

Please or to participate in this conversation.