Installation:
composer require lapaliv/laravel-bulk-upsert
Add Trait to Model:
use Lapaliv\BulkUpsert\Bulkable;
class User extends Model {
use Bulkable;
}
First Use Case:
$data = [
['email' => 'john@example.com', 'name' => 'John'],
['email' => 'david@example.com', 'name' => 'David'],
];
User::query()->bulk()->uniqueBy('email')->create($data);
Bulk Creation with Events:
$bulk = User::bulk()->onCreating(fn(User $user) => $user->setAttribute('active', true));
$bulk->uniqueBy('email')->createAndReturn($data);
Chunked Processing:
$bulk->chunk(100);
foreach ($largeDataset as $item) {
$bulk->createOrAccumulate($item);
}
$bulk->createAccumulated();
Upsert with Related Data:
User::bulk()
->uniqueBy('email')
->upsert($usersWithComments)
->onSavedMany(fn($users, $bulkRows) => $this->handleComments($bulkRows));
savedMany to trigger cascading operations (e.g., creating related models).onCreating/onUpdating callbacks.DB::transaction(fn() => $bulk->upsert($data));
Dynamic Unique Keys:
$bulk->uniqueBy(fn(array $item) => $item['email'] ?? $item['username']);
Conditional Processing:
$bulk->onCreating(fn(User $user) => $user->email === 'admin@example.com' ? false : null);
Event Order:
onSaving runs before onCreating/onUpdating. Return false in onSaving to skip all subsequent events.onCreatingMany/onUpdatingMany receive a BulkRows object; ensure you handle its structure.Field Alignment:
fillable attributes in your model override this. Ensure fillable matches your data structure.Soft Deletes:
delete) respect SoftDeletes trait, but forceDelete bypasses it. Verify your model’s deleted_at column.Performance:
DB::enableQueryLog().Log Events:
$bulk->onCreating(fn(User $user) => logger()->debug('Creating:', $user->toArray()));
Inspect BulkRows:
$bulk->onSavedMany(fn($users, $bulkRows) => logger()->debug($bulkRows->first()->original));
Validate Data:
Use onCreating to log or validate data before bulk operations:
$bulk->onCreating(fn(User $user) => $user->email ? null : logger()->error('Missing email'));
Custom BulkRow:
Extend Lapaliv\BulkUpsert\Entities\BulkRow to add metadata:
class CustomBulkRow extends BulkRow {
public function __construct(array $original, Model $model, array $unique) {
parent::__construct($original, $model, $unique);
$this->original['custom_field'] = 'value';
}
}
Override Query Builder: Replace the default query builder by binding a custom instance:
$bulk = new Bulk(User::class, app()->make(CustomQueryBuilder::class));
Batch Processing:
Use chunk() with a callback for async processing:
$bulk->chunk(50, fn($chunk) => dispatch(new ProcessChunk($chunk)));
100. Adjust via config(['bulk-upsert.chunk_size' => 200]).id handling due to auto-increment behavior.How can I help you explore Laravel packages today?