Skip to content

Conversation

@cosmastech
Copy link
Contributor

@cosmastech cosmastech commented Oct 30, 2025

It's really, really easy to write inefficient tests by leveraging Order::factory()->count(100)->create() not realizing that it's going to run 100 inserts. I just fixed this in a number of tests this week.

Here we add a Factory@insert() method that allows performing a mass insert of models.

Note that this does not return anything (it's akin to the Eloquent model's insert() method), and similarly does not emit Model events. This is only really useful if you need to insert lot of some model in your database, but don't actually need those models handy in the test. Think of testing pagination or how a resource returns a count.

@cosmastech cosmastech marked this pull request as draft October 30, 2025 22:23
@browner12
Copy link
Contributor

Is there a limitation that prevents you from returning the collection?

If you can get this to work that'd be great. I think there is some nuance and complications though with multiple inserts and things like model events not triggering that you'd have to deal with. Probably part of the same reason we don't have a save() method on the Eloquent/Collection yet.

@cosmastech
Copy link
Contributor Author

cosmastech commented Oct 30, 2025

Is there a limitation that prevents you from returning the collection?

If you can get this to work that'd be great. I think there is some nuance and complications though with multiple inserts and things like model events not triggering that you'd have to deal with. Probably part of the same reason we don't have a save() method on the Eloquent/Collection yet.

Generated IDs won't be available, for instance. We could return the collection, but it would be like a sharp knife falling in a kitchen.

It is probably worth noting in the docblock that model events aren't fired, which is by design (because they require the single insert approach)

@cosmastech cosmastech marked this pull request as ready for review October 31, 2025 01:34
@cosmastech cosmastech changed the title [12.x] Factory@insert() [12.x] Factory@insert() Oct 31, 2025
@shaedrich
Copy link
Contributor

You could have gone with returning an Eloquent collection just like createMany(). This method could be named something like massCreateMany(), however, this wouldn't follow the createMany*() convention of the other related methods.

@taylorotwell taylorotwell merged commit a91b059 into laravel:12.x Oct 31, 2025
65 of 66 checks passed
@cosmastech cosmastech deleted the factory-insert branch October 31, 2025 17:20
@jasonmccreary
Copy link
Contributor

@shaedrich, I think void is appropriate here. It avoids any testing footguns where you might try to use the result in a later assertion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants