mateusjatenee / laravel-persist
This is my package laravel-persist
Installs: 1 491
Dependents: 0
Suggesters: 0
Security: 0
Stars: 73
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- php: ^8.1
- illuminate/contracts: ^10.0|^11.0
- illuminate/database: ^10.0|^11.0
Requires (Dev)
- laravel/pint: ^1.0
- nunomaduro/larastan: ^2.0.1
- orchestra/testbench: ^8.8|^9.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^10.0|^11.0
README
Introduction
The package offers an extension on top of Eloquent, enabling developers to handle the persistence of entire object graphs as a single unit of work. This package simplifies managing complex data models with multiple interrelated entities, ensuring a more efficient and reliable data handling process.
It works similarly to the native push
method, but push
does not persist any records for the first time. Therefore, you cannot build an object with its relationships and use push
to save everything.
Persist works by hooking on two specific pieces of the lifecycle:
- When you assign a property (e.g
$post->owner = $user
), the package checks whether that property is a relation, and if so, callssetRelation
to properly set it. - When you call the
persist
method, it works in a similar fashion topush
, but it adds hooks to persist the related objects before or after the base object. There are subtle differences on persistence order for different relationship types.
On top of that, Persist also runs the entire operation inside a database transaction. This means that if any part of the object graph fails to persist, the entire operation will be rolled back, maintaining database integrity.
Installation
You can install the package via composer:
composer require mateusjatenee/laravel-persist
Usage
Simply add the Persist
trait to your models. For example:
namespace App\Models; class Order extends Model { use Persist; }
Now you'll be able to persist the entire object graph using the persist
method. For example:
class ProcessCheckoutHandler { public function __construct( private DatabaseManager $database, ) { } public function handle(ProcessCheckout $command) { $order = Order::startForCustomer($command->customer->id); $order->lines->push($command->cartItems->toOrderLines()); // Pushes an object to the "lines" relationship, which is a HasMany relation. $charge = $command->gateway->pay($command->pendingPayment); $order->payment = Payment::fromCharge($charge); // Sets the payment relationship, a "BelongsTo" relation. $order->payment->customer = $command->customer; // Sets the customer relationship "2-levels deep". $order->persist(); return $order; } }
In the example above, 4 entities will be persisted to the database: Order
, OrderLine
, Payment
, and Customer
.
persist
runs, by default, within a transaction, so that if any queries fail, the entire transaction is rolled back.
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Credits
License
The MIT License (MIT). Please see License File for more information.