mateusjatenee/laravel-persist

这是我的包laravel-persist

0.3.0 2024-06-04 16:19 UTC

This package is auto-updated.

Last update: 2024-09-08 05:37:06 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

简介

该包在Eloquent之上提供了扩展,使开发者能够将整个对象图作为单个工作单元来处理持久性。这个包简化了管理具有多个相互关联实体的复杂数据模型,确保了更高效和可靠的数据处理过程。

它的工作方式类似于原生的push方法,但push在第一次时不持久化任何记录。因此,您不能使用push来保存包含其关系的对象。

Persist通过钩子连接两个特定的生命周期片段

  1. 当您分配一个属性(例如$post->owner = $user)时,该包会检查该属性是否为关系,如果是,则调用setRelation来正确设置它。
  2. 当您调用persist方法时,它的工作方式与push类似,但它会添加钩子以在基对象之前或之后持久化相关对象。对于不同类型的关系,持久化顺序存在细微差异。

除此之外,Persist还在数据库事务中运行整个操作。这意味着如果对象图的任何部分无法持久化,整个操作将被回滚,以保持数据库的完整性。

安装

您可以通过composer安装此包

composer require mateusjatenee/laravel-persist

使用方法

简单地将Persist特性添加到您的模型中。例如

namespace App\Models;

class Order extends Model
{
    use Persist;
}

现在您可以使用persist方法来持久化整个对象图。例如

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;
    }
}

在上面的例子中,将向数据库持久化4个实体:OrderOrderLinePaymentCustomer
persist默认在事务中运行,所以如果任何查询失败,整个事务将被回滚。

测试

composer test

变更日志

有关最近更改的更多信息,请参阅变更日志

贡献

有关详细信息,请参阅贡献指南

鸣谢

许可

MIT许可(MIT)。有关更多信息,请参阅许可文件