brahmic/laravel-filler

Laravel Eloquent 数据库填充器

1.0.0 2024-06-23 22:48 UTC

This package is auto-updated.

Last update: 2024-09-24 09:46:27 UTC


README

Latest Version on Packagist GitHub Tests Action Status

概念

在通过API处理数据时,我们经常接收到具有嵌套关系的实体,但在发送数据时,嵌套关系必须手动处理。这个加湿包允许您无需考虑它。这大大加快了开发速度。

特性

  • 允许您“原样”处理Eloquent模型的数据输入和输出,无需不必要的操作
  • 工作单元 - 要么全部更改,要么(在出现错误的情况下)不进行任何更改
  • 身份映射 - 保证具有相同类型和相同标识符的实体在本质上是相同的
  • uuid - 允许您通过标识符创建有效的实体并将它们连接起来,而无需访问数据库

内容

限制

目前仅支持uuid

安装

composer require brahmic/laravel-filler

使用

这个功能非常易于使用

👆

后端示例

<?php

namespace App\Http\Controllers;

use App\Post;
use Exception;
use Brahmic\Filler\Filler;
use Illuminate\Http\Request;

class PostController
{
 /**
 * @param $id
 * @param Request $request
 * @param Filler $filler
 * @return Post
 * @throws Exception
 */
 public function put(Request $request, Filler $filler): Post
 {
     $post = Post::findOrNew($request->get('id'));
     $filler->filler($post, $request->all());
    
     // here we can do something before the changes are sent to the database.
    
     $filler->flush();
    
     return $post;
 }
}

👆

前端示例

(不要这样做 - 这只是一个示例)

import uuid from 'uuid/v4'

class Post {
    constructor(data) {
        if (!data.id) {
            data.id = uuid()
        }
        Object.assign(this, data)
    }

    addTag(tag) {
        this.tags.push(tag)
    }

    addImage(image) {
        this.images.push(image)
    }
}

class Tag {
    constructor(data) {
        if (!data.id) {
            data.id = uuid()
        }
        Object.assign(this, data)
    }
}

let post, tags;

//
function loadTags() {
    fetch('tags')
        .then(response => response.json())
        .then(tagsData => tags = data.map(tagdata => new Tag(tagdata)))

}

function loadPost(id) {
    fetch(`posts/${id}`)
        .then(response => response.json())
        .then(data => post = new Post(data))
}

function savePost(post) {
    fetch(`posts/${post.id}`, {method: 'PUT', body: JSON.stringify(post)})
        .then(response => response.json())
        .then(data => alert(`Post ${data.title} saved!`))
}

loadTags()
loadPost(1)

// After everything is loaded:

post.addTag(tags[0])
post.title = 'Hello World!'

savePost(post)

👆

输入特性

扁平实体

让我们举一个简单的例子

{
  "name": "Brahmic",
  "email": "mail@example.com"
}

由于传递的数据不包含id字段(或模型中指定在$primaryKey中的另一个字段),加湿器将创建一个新的实体。并使用标准的fill方法用传输的数据填充它。在这种情况下,将立即为模型生成一个id

带有ID的示例

{
  "id": "123e4567-e89b-12d3-a456-426655440000",
  "name": "Brahmic",
  "email": "mail@example.com"
}

在这个示例中,传递了id - 因此加湿器将尝试在数据库中找到这样的实体。然而,如果它在数据库中找不到这样的记录,它将使用传递的id创建一个新的实体。无论如何,加湿器都将使用传递的emailname填充这个模型。在这种情况下,行为类似于User::findORNew($id)

👆

HasOne

{
  "id": "123e4567-e89b-12d3-a456-426655440000",
  "name": "Brahmic",
  "email": "mail@example.com",
  "account": {
    "active": true
  }
}

在这种情况下,加湿器将以与带有标识符的示例相同的方式处理第一级实体(用户)。然后,它将尝试找到账户 - 如果它找不到(在当前示例中账户没有id),它将创建一个新的账户。如果它找到一个具有不同标识符的账户,它将用新创建的账户替换它。旧账户将被删除。当然,在任何后端字段(例如user_idauthor_id - 取决于它是如何相对于User::account()指定的),将写入用户ID。

👆

HasMany

{
  "id": "123e4567-e89b-12d3-a456-426655440000",
  "name": "Brahmic",
  "email": "mail@example.com",
  "posts": [
    {
      "id": "1286d5bb-c566-4f3e-abe0-4a5d56095f01",
      "title": "foo",
      "text": "bar"
    },
    {
      "id": "d91c9e65-3ce3-4bea-a478-ee33c24a4628",
      "title": "baz",
      "text": "quux"
    },
    {
      "title": "baz",
      "text": "quux"
    }
  ]
}

在多对一示例中,加湿器会随着每个帖子条目出现,就像在HasOne示例中一样。此外,所有不在传递的帖子数组中的帖子都将被删除。

👆

BelongsTo

{
  "id": "123e4567-e89b-12d3-a456-426655440000",
  "name": "Brahmic",
  "email": "mail@example.com",
  "organization": {
    "id": "1286d5bb-c566-4f3e-abe0-4a5d56095f01",
    "name": "Acme"
  }
}

尽管这个示例看起来像HasOne,但它的操作方式不同。如果加湿器在数据库中找到了这样的组织,用户将通过关系字段与之关联。另一方面,如果没有这样的记录,用户将在这个字段中收到null。将忽略关联记录的所有其他字段(组织) - 因为User不是Organization聚合根,因此无法通过用户对象操作组织字段,也无法创建新的组织。

👆

BelongsToMany

{
  "id": "123e4567-e89b-12d3-a456-426655440000",
  "name": "Brahmic",
  "email": "mail@example.com",
  "roles": [
    {
      "id": "dcb41b0c-8bc1-490c-b714-71a935be5e2c",
      "pivot": {
        "sort": 0
      }
    }
  ]
}

此示例类似于HasMany(在所有非表示记录将从关联表中删除的意义上)和BlongsTo(如上所述在belongsTo部分中解释的原因,除了$primaryKey字段外,所有字段都将被忽略)。请注意,也可以与关联表一起使用。

MorphTo

支持,但尚未描述。操作原理与上述描述类似。

MorphOne

支持,但尚未描述。操作原理与上述描述类似。

MorphMany

支持,但尚未描述。操作原理与上述描述类似。

所有描述的内容都是递归的,并且对任何级别的嵌套都有效。

👆

输出功能

还值得注意的是,所有传递的关系将在输出时添加到实体中。例如

 $user = $filler->filler(User::class, [
 'id' => '123e4567-e89b-12d3-a456-426655440000',
 'name' => 'Brahmic',
 'email' => 'mail@example.com',
 'roles' => [
         [
             'id' => 'dcb41b0c-8bc1-490c-b714-71a935be5e2c',
             'pivot' => ['sort' => 0],
         ],
     ],
 ]);

 $user->relationLoaded('roles'); // true
 // although the flush has not been done yet, all relationships have already been registered, and there is no need to load them additionally.
 // Calling $user->roles will not cause a repeated request to the database.

 $filler->flush();
 // Only after this the entity with all its connections will be included in the database.

👆

待办事项

  • 添加持久化未通过数据填充器传递的实体的功能
  • 在readme中添加多态关系的描述

👆