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.
You can install the package via composer:
composer require mateusjatenee/laravel-persist
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.
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
The MIT License (MIT). Please see License File for more information.