承接 brandonkerr/eloquent-from-settings 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

brandonkerr/eloquent-from-settings

Composer 安装命令:

composer require brandonkerr/eloquent-from-settings

包简介

Easily generate eloquent models and relationships from JSON or array

README 文档

README

Packagist Version Tests Static Analysis codecov

This package allows you to easily build Eloquent models and their relationships, through data settings via array or JSON passed to the model's factory.

Installation

Install the package via composer:

composer require brandonkerr/eloquent-from-settings

First, ensure that your model has a factory:

namespace App\Models;

// ...
use Illuminate\Database\Eloquent\Factories\HasFactory;

class User extends Authenticatable 
{
    use HasFactory;
    // ...
}

Then simply add the FromSettings trait to your factory:

namespace Database\Factories;

// ...
use Brandonkerr\EloquentFromSettings\Traits\FromSettings;

class UserFactory extends Factory
{
    use FromSettings;
    // ...
}

Configuration

By default, the FromSettings trait behaves strictly and will throw:

  • a MissingTraitException if a keyed relationship does not use the FromSettings trait
  • an UnknownKeyException if a key cannot be matched to an attribute, relationship, or function

While this is the recommended behaviour to ensure data integrity, you have the freedom to change these settings.

If you would like to allow for a keyed relationship that does not use the FromSettings trait, you can either set the $throwsMissingTraitException property to false:

class FooFactory extends Factory
{
    use FromSettings;
    
    public bool $throwsMissingTraitException = false;
    
    // ...
}

or for a customized logic, implement FromSettingsInterface and complete the getThrowsMissingTraitException() function:

class BarFactory extends Factory implements FromSettingsInterface
{
    use FromSettings;
    
    public function getThrowsMissingTraitException(): bool
    {
        return $this->someCustomSettingOrLogic;
    }
    
    // ...
}

If you would like to allow for unknown keys to be silently dropped, you can either set the $throwsUnknownKeyException property to false:

class FooFactory extends Factory
{
    use FromSettings;
    
    public bool $throwsUnknownKeyException = false;
    
    // ...
}

or for a customized logic, implement FromSettingsInterface and complete the getThrowsUnknownKeyException() function:

class BarFactory extends Factory implements FromSettingsInterface
{
    use FromSettings;
    
    public function getThrowsUnknownKeyException(): bool
    {
        return $this->someCustomSettingOrLogic;
    }
    
    // ...
}

Usage

Simply pass the desired settings via array to the factor's fromSettingsArray function:

$data = [
        "name" => "Brandon Kerr",
        "books" => [
            [
                "title" => "How to Use Eloquent From Settings",
                "reviews" => [
                    [
                        "reviewer" => "Jane Doe",
                        "score" => 80,
                    ],
                    [
                        "reviewer" => "John Smith",
                        "score" => 45,
                    ],
                ],
            ],
        ],
    ];
Author::factory()->fromSettingsArray(...$data)->create();

or via JSON to the factor's fromSettingsJson function:

$json = '{
   "name":"Brandon Kerr",
   "books":[
      {
         "title":"How to Use Eloquent From Settings",
         "reviews":[
            {
               "reviewer":"Jane Doe",
               "score":80
            },
            {
               "reviewer":"John Smith",
               "score":45
            }
         ]
      }
   ]
}';
Author::factory()->fromSettingsJson($json)->create();

The end result will be

  • an Author model with name Brandon Kerr
  • a Book model whose Author is created above and title is How to Use Eloquent From Settings
  • a Review for the Book created above with reviewer Jane Doe and a score of 80
  • a Review for the Book created above with reviewer John Smith and a score of 45

Full Example

This example covers Authors writing Books, which have Reviews. Full details can be found in the tests directory of this package.

Models and Schemas

Refer to the Models and Migrations directories under tests/Stubs for full details.

Author

Column/Attribute Type Notes
id unsigned bigint Primary Key
name string unique constraint added for use in a custom function test
  • an Author HasMany Books
  • an Author HasManyThrough Reviews (through Books)

Book

Column/Attribute Type Notes
id unsigned bigint Primary Key
title string title of the book
author_id unsigned bigint Foreign Key to Author
  • a Book BelongsTo an Author
  • a Book HasMany Reviews

Review

Column/Attribute Type Notes
id unsigned bigint Primary Key
reviewer string name of the reviewer
score integer the score (out of 100)
book_id unsigned bigint Foreign Key to Book
  • a Review BelongsTo a Book

Factories

The AuthorFactory and ReviewFactory classes are completely standard (aside from using the FromSettings trait), but the BookFactory has two custom functions to showcase additional functionality of this package:

 /**
 * Custom function to find or create the author, based on the given name
 *
 * @param string $name
 * @return $this
 */
public function forAuthor(string $name): self
{
    $author = Author::firstOrCreate([
        "name" => $name
    ]);

    return $this->state(["author_id" => $author->id]);
}

/**
 * Custom function to add reviews with a perfect score
 *
 * @param string ...$names
 * @return $this
 */
public function perfectReviews(string ...$names): self
{
    return $this->has(
        Review::factory()
            ->count(count($names))
            ->sequence(fn (Sequence $sequence) => [
                "reviewer" => $names[$sequence->index],
                "score" => 100,
            ])
    );
}

Settings Data

Below is a commented example of an array of settings, where the author is the root of the data:

$data = [
        // the author's name attribute
        "name" => "Bob",
        // the author's HasMany relationship with Book
        "books" => [
            // first book
            [  
                // the book's title attribute
                "title" => "Bob's First Book",
                // the book's HasMany relationship with Review
                "reviews" => [
                    // first review
                    [
                        // the review's reviewer attribute
                        "reviewer" => "Jane Doe",
                        // the review's score attribute
                        "score" => 80,
                    ],
                    // second review
                    [
                        // the review's reviewer attribute
                        "reviewer" => "John Smith",
                        // the review's score attribute
                        "score" => 45,
                    ],
                ],
            ],
            // second book
            [
                // the book's title attribute
                "title" => "Please Don't Review Me",
                // NOTE no reviews 
            ],
        ],
    ];

Then we simply call the Author's factory:

$author = Author::factory()->fromSettingsArray(...$data)->create();

The end result is

  • One Author with name Bob, which has two books:
    • The first book is titled Bob's First Book and has two reviews:
      • one with reviewer Jane Doe and a score of 80, and
      • one with reviewer John Smith and a score of 45.
    • The second book is titled Please Don't Review Me and has zero reviews.

BelongsTo

We aren't limited to Has__ relationships, like in the example above. We can also use a Book as the data root, and create an author for it:

$data = [
    "title" => "My Book",
    "author" => [
        "name" => "Bob Jones",
    ],
];
Book::factory()->fromSettingsArray(...$data)->create();

The end result is one Author named Bob Jones, which has one Book titled My Book.

Custom Functions

But what if we don't want to create a new author, and don't know the author's ID that we could use to set the book's author_id value? You could create a custom function on the Book's factory that can find the author by their name, and assign the author to the book. See the forAuthor() function above for details.

Author::create([
    "name" => "Bob Jones"
]);
// ...
$data = [
    "title" => "My Book",
    "forAuthor" => [
        "name" => "Bob Jones",
    ],
];

$book = Book::factory()->fromSettingsArray(...$data)->create();

The end result is again one Author named Bob Jones, which has one Book titled My Book, but since the Author named Bob Jones already existed, it would not be created again, and it would not violate our unique name constraint on the Authors table.

We can also use a custom function to accept non key-value pair settings. See the perfectReviews() function above for details.

$data = [
    "title" => "My Book",
    "author" => [
        "name" => "Bob Jones",
    ],
    "perfectReviews" => [
        [
            "Jane Doe",
        ],
        [
            "John Smith",
        ],
    ],
];

The end result is once again one Author named Bob Jones, which has one Book titled My Book. However, this time the Book has two Reviews: one with reviewer Jane Doe, and the other with reviewer John Smith, and both with a score of 100 (as set by the perfectReviews function).

License

This package is open-sourced software licensed under the MIT license.

brandonkerr/eloquent-from-settings 适用场景与选型建议

brandonkerr/eloquent-from-settings 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 10 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 04 月 08 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「database」 「factory」 「laravel」 「Settings」 「eloquent」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 brandonkerr/eloquent-from-settings 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 brandonkerr/eloquent-from-settings 我们能提供哪些服务?
定制开发 / 二次开发

基于 brandonkerr/eloquent-from-settings 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 10
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 9
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-04-08