-
Notifications
You must be signed in to change notification settings - Fork 11.7k
[12.x] Factory@insert()
#57600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[12.x] Factory@insert()
#57600
Conversation
|
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 |
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) |
|
You could have gone with returning an Eloquent collection just like |
|
@shaedrich, I think |
|
@cosmastech I think there's a bug somewhere, hadn't enough time yet to look exactly why its happening. But all Eloquent The implementation is using Confirmed, did a hacky test. Maybe there's a better implementation than this: $query->fillAndInsert(
$madeCollection->withoutAppends()->setHidden([])->toArray()
); |
|
@cosmastech Question about the implementation. The User::factory(10)->has(Article::factory()->count(3))->insert();Is that an intended? Is it possible to fallback to single-row inserts for relationships? Or better, use multi-row inserts too? |
I think it was intended, but not mentioned, that afterCreate or attaching relationships won't work. This is because this method doesn't know the rows to attach to. We could pull records based on maybe Is there any other way that you can envision where this would be possible? I do not feel that falling back to single-row inserts is the right approach. I think it's better to have a function which operates consistently. |
I think this was fixed via #57670. Added a test in a PR here. #57722 |
|
Looks like this is currently broken for array cast json columns, @cosmastech. The entire stored array gets wrapped in double quotes. |
@zepfietje can you give me a quick example of the model you built and the factory it fails for? 🙏 |
|
Sure! Minimal reproduction: <?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('foos', function (Blueprint $table) {
$table->id();
$table->json('bar');
$table->timestamps();
});
}
};<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Foo extends Model
{
/** @use HasFactory<\Database\Factories\FooFactory> */
use HasFactory;
protected function casts(): array
{
return [
'bar' => 'array',
];
}
}<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Foo>
*/
class FooFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'bar' => ['bar'],
];
}
}Running |
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.