brandonkerr / eloquent-from-settings
轻松从 JSON 或数组生成 eloquent 模型和关系
Requires
- php: ^8.1
- illuminate/database: ^9.22|^10.0
- illuminate/support: ^9.22|^10.0
Requires (Dev)
- laravel/pint: ^1.8
- orchestra/testbench: ^8.2
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6
This package is auto-updated.
Last update: 2024-09-17 22:02:08 UTC
README
此包允许您通过通过传递给模型工厂的数组或 JSON 数据设置轻松构建 Eloquent 模型和它们的关系。
安装
使用 composer 安装此包
composer require brandonkerr/eloquent-from-settings
首先,确保您的模型有一个工厂
namespace App\Models; // ... use Illuminate\Database\Eloquent\Factories\HasFactory; class User extends Authenticatable { use HasFactory; // ... }
然后只需将 FromSettings
特性添加到您的工厂中
namespace Database\Factories; // ... use Brandonkerr\EloquentFromSettings\Traits\FromSettings; class UserFactory extends Factory { use FromSettings; // ... }
配置
默认情况下,FromSettings
特性行为严格,如果键关系没有使用 FromSettings 特性,则将抛出
MissingTraitException
- 如果无法将键匹配到属性、关系或函数,则抛出
UnknownKeyException
尽管这是确保数据完整性的推荐行为,但您有自由更改这些设置。
如果您想允许键关系不使用 FromSettings 特性,您可以设置 $throwsMissingTraitException
属性为 false
class FooFactory extends Factory { use FromSettings; public bool $throwsMissingTraitException = false; // ... }
或实现 FromSettingsInterface
并完成 getThrowsMissingTraitException()
函数以进行自定义逻辑
class BarFactory extends Factory implements FromSettingsInterface { use FromSettings; public function getThrowsMissingTraitException(): bool { return $this->someCustomSettingOrLogic; } // ... }
如果您想允许静默删除未知键,您可以设置 $throwsUnknownKeyException
属性为 false
class FooFactory extends Factory { use FromSettings; public bool $throwsUnknownKeyException = false; // ... }
或实现 FromSettingsInterface
并完成 getThrowsUnknownKeyException()
函数以进行自定义逻辑
class BarFactory extends Factory implements FromSettingsInterface { use FromSettings; public function getThrowsUnknownKeyException(): bool { return $this->someCustomSettingOrLogic; } // ... }
用法
简单地将所需的设置通过数组传递给工厂的 fromSettingsArray
函数
$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();
或通过 JSON 传递给工厂的 fromSettingsJson
函数
$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();
最终结果将是
- 一个名为 Brandon Kerr 的作者模型
- 一个作者模型,其作者是上面创建的,标题是 如何使用 Eloquent From Settings
- 对上面创建的书的评论,评论者是 Jane Doe,评分为 80
- 对上面创建的书的评论,评论者是 John Smith,评分为 45
完整示例
此示例涵盖作者撰写书籍,这些书籍有评论。完整详情可在此包的测试目录中找到。
模型和模式
有关详细信息,请参阅 tests/Stubs 下的 Models 和 Migrations 目录。
作者
- 一个作者
HasMany
书籍 - 一个作者
HasManyThrough
评论(通过书籍)
书籍
- 一个书籍
BelongsTo
作者 - 一个书籍
HasMany
评论
评论
- 一个评论
BelongsTo
一本书
工厂
AuthorFactory
和 ReviewFactory
类完全标准(除了使用 FromSettings
特性外),但 BookFactory
有两个自定义函数以展示此包的附加功能
/** * 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, ]) ); }
设置数据
以下是设置数组的示例,其中作者为数据根
$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 ], ], ];
然后我们简单地调用作者的工厂
$author = Author::factory()->fromSettingsArray(...$data)->create();
最终结果是
- 一个名为 Bob 的作者,该作者有两本书
- 第一本书名为 Bob 的第一本书,有两篇评论
- 一篇评论者是 Jane Doe,评分为 80,和
- 一篇评论者是 John Smith,评分为 45。
- 第二本书名为 请不要评论我,没有评论。
- 第一本书名为 Bob 的第一本书,有两篇评论
BelongsTo
我们不仅限于像上面示例中的Has__关系。我们还可以将书作为数据根,并为它创建一个作者。
$data = [ "title" => "My Book", "author" => [ "name" => "Bob Jones", ], ]; Book::factory()->fromSettingsArray(...$data)->create();
最终结果是名为Bob Jones的一位作者,他有一本名为我的书的书。
自定义函数
但如果我们不想创建一个新的作者,也不知道可以用什么作者的ID来设置书的author_id值呢?你可以在书的工厂中创建一个自定义函数,通过名字找到作者,并将其分配给书。有关forAuthor()
函数的详细信息,请参见上方。
Author::create([ "name" => "Bob Jones" ]); // ... $data = [ "title" => "My Book", "forAuthor" => [ "name" => "Bob Jones", ], ]; $book = Book::factory()->fromSettingsArray(...$data)->create();
最终结果依然是名为Bob Jones的一位作者,他有一本名为我的书的书。但由于名为Bob Jones的作者已经存在,所以不会再次创建,也不会违反我们在作者表中对唯一名字的约束。
我们还可以使用自定义函数来接受非键值对设置。有关perfectReviews()
函数的详细信息,请参见上方。
$data = [ "title" => "My Book", "author" => [ "name" => "Bob Jones", ], "perfectReviews" => [ [ "Jane Doe", ], [ "John Smith", ], ], ];
最终结果依然是名为Bob Jones的一位作者,他有一本名为我的书的书。然而,这次书有两个评论:一个是评论者Jane Doe的评论,另一个是评论者John Smith的评论,两者评分都是100(由perfectReviews
函数设置)。
许可证
本软件包是开源软件,采用MIT许可证授权。