I often find myself seeding huge lists of data in Laravel that need to be ordered. Using sequences in factories, we can create a more realistic list of data by incrementing the created_at date.
We use this technique in some of our courses. Check them out, you'll find plenty more tricks like this too.
Let's imagine we have a Message
model. A seeder using a factory would look like this:
public function run(): void
{
Message::factory()
->times(5000)
->create();
}
When this seeder runs and creates 5000 records, the created_at
date will be pretty much the same for every record, so unfortunately, when we order the records with orderBy
or latest
, it won't represent any real order.
We can leverage sequences in factories that run for every record being created.
Here's how I usually implement these:
public function run(): void
{
Message::factory()
->times(5000)
->sequence(function (Sequence $sequence) {
return [
'created_at' => now()->subHour($sequence->index)
];
})
->create();
}
The sequence
callback gives us a Sequence
object for every 5000 records we generate here. Because this object contains an index
(starting at 0), we can modify the created_at
date for every record by subtracting an hour.
Feel free to update the state inside the sequence to modify the created_at
date in any way. Most importantly, all our records will now have an orderable created_at
date!