wpstarter / c-sushi
Eloquent 缺失的 "array" 驱动器。
Requires
- php: ^7.1.3|^8.0
- wp-starter/database: ^1.0
- wp-starter/support: ^1.0
Requires (Dev)
- doctrine/dbal: ^3.1.4
- phpunit/phpunit: ^8.4 || ^9.0
- wpstarter/o-testbench: ^1.0
This package is auto-updated.
Last update: 2024-08-24 10:41:04 UTC
README
Eloquent 缺失的 "array" 驱动器。
有时你想使用 Eloquent,但又不想处理数据库。
此包为赞助软件 💰💰💰
最初,此包仅通过 GitHub Sponsors 的赞助者提供,直到我达到 75 名赞助者。
现在我们已经达到目标,该包完全开源。
享受,并感谢您的支持! ❤️
在 github.com/sponsorware/docs 了解更多关于 赞助软件 的信息 💰。
安装
composer require calebporzio/sushi
使用
使用此包包括两个步骤
- 将
Sushi
特性添加到模型中。 - 将
$rows
属性添加到模型中。
就是这样。
class State extends Model { use \Sushi\Sushi; protected $rows = [ [ 'abbr' => 'NY', 'name' => 'New York', ], [ 'abbr' => 'CA', 'name' => 'California', ], ]; }
现在,您可以在任何地方使用此模型,它将表现得好像您已创建了一个包含您提供的行的表。
$stateName = State::whereAbbr('NY')->first()->name;
这对于 "固定" 数据非常有用,例如州、国家、邮政编码、用户角色、站点设置等...
关系
假设您创建了一个基于数组的 Role
模型,使用 Sushi,它看起来像这样
class Role extends Model { use \Sushi\Sushi; protected $rows = [ ['id' => 1, 'label' => 'admin'], ['id' => 2, 'label' => 'manager'], ['id' => 3, 'label' => 'user'], ]; }
您可以将关系添加到另一个标准模型,就像您通常所做的那样
class User extends Model { ... public function role() { return $this->belongsTo(Role::class); } }
假设 users
表有一个 role_id
列,您可以这样做
// Grab a User. $user = User::first(); // Grab a Role. $role = Role::whereLabel('admin')->first(); // Associate them. $user->role()->associate($role); // Access like normal. $user->role; // Eager load. $user->load('role'); User::with('role')->first();
注意:处理 Sushi 模型关系时有一个注意事项。
whereHas
方法将不会工作。这是因为两个模型分布在两个不同的数据库中。
使用数据库检查验证规则
您甚至可以使用 Laravel 的 exists:table,column
数据库检查请求验证规则。
$data = request()->validate([ 'state' => ['required', 'exists:App\Model\State,abbr'], ]);
注意:请注意,您必须使用模型的完全限定命名空间,而不是表名。这确保 Laravel 正确解析模型连接。
自定义模式
如果 Sushi 的模式自动检测系统不能满足您对提供的行数据的特定要求,您可以使用 $schema
属性或 getSchema()
方法来自定义它们。
class Products extends Model { use \Sushi\Sushi; protected $rows = [ ['name' => 'Lawn Mower', 'price' => '226.99'], ['name' => 'Leaf Blower', 'price' => '134.99'], ['name' => 'Rake', 'price' => '9.99'], ]; protected $schema = [ 'price' => 'float', ]; }
它是如何工作的
在底层,此包为该模型创建并缓存一个 SQLite 数据库。它创建一个表并填充行。如果由于任何原因无法缓存 .sqlite 文件,它将默认使用内存中的 sqlite 数据库。
使用 ->getRows()
您可以选择不使用 protected $rows
属性,而是直接实现自己的 getRows()
方法。
这将允许您在运行时确定模型的行。您甚至可以从第三方 API 等外部源生成模型的行。
class Role extends Model { use \Sushi\Sushi; public function getRows() { return [ ['id' => 1, 'label' => 'admin'], ['id' => 2, 'label' => 'manager'], ['id' => 3, 'label' => 'user'], ]; } }
缓存 ->getRows()
如果您选择使用自己的 ->getRows() 方法,则默认情况下不会在请求之间缓存行。
您可以使用以下方法强制 Sushi 缓存您的数据集:sushiShouldCache()
。
以下是一个示例配置,说明如何将 ->getRows()
数据集进行缓存
class Role extends Model { use \Sushi\Sushi; public function getRows() { return [ ['id' => 1, 'label' => 'admin'], ['id' => 2, 'label' => 'manager'], ['id' => 3, 'label' => 'user'], ]; } protected function sushiShouldCache() { return true; } }
默认情况下,Sushi 会查看您的模型 PHP 文件的“最后修改时间戳”,并将其与内部的 .sqlite
缓存文件进行比较。如果模型文件比 .sqlite
缓存文件修改得更晚,那么 Sushi 将会销毁并重建 .sqlite
缓存。此外,您还可以配置一个外部文件,让 Sushi 在确定缓存是否更新或需要刷新时参考。
例如,如果您使用 Sushi 为外部数据源文件(如 .csv
文件)提供一个 Eloquent 模型,您可以使用 sushiCacheReferencePath
强制 Sushi 在确定缓存是否过时时参考 .csv
文件。
例如
class Role extends Model { use \Sushi\Sushi; public function getRows() { return CSV::fromFile(__DIR__.'/roles.csv')->toArray(); } protected function sushiShouldCache() { return true; } protected function sushiCacheReferencePath() { return __DIR__.'/roles.csv'; } }
现在,Sushi 只有在 roles.csv
发生更改时才会“破坏”其内部缓存,而不是查看 Role.php
模型。
处理空数据集
Sushi 会读取您的数据集的第一行来推断 SQLite 表的方案。如果您使用 getRows()
并且这返回一个空数组(例如 API 没有返回任何内容),那么 Sushi 会抛出错误。
如果您希望 Sushi 即使数据集为空也能工作,您可以在可选的 protected $schema
数组中定义您的方案。
注意:如果您选择使用自己的 ->getRows() 方法,行之间不会在请求之间进行缓存。
class Currency extends Model { use \Sushi\Sushi; protected $schema = [ 'id' => 'integer', 'name' => 'string', 'symbol' => 'string', 'precision' => 'float' ]; public function getRows() { return []; } }
处理基于字符串的主键
如果您的模型使用基于字符串的主键,Sushi 需要您在模型中添加两个属性 - $incrementing
和 $keyType
class Role extends Model { use \Sushi\Sushi; public $incrementing = false; protected $keyType = 'string'; protected $rows = [ ['id' => 'admin', 'label' => 'Admin'], ['id' => 'manager', 'label' => 'Manager'], ['id' => 'user', 'label' => 'User'], ]; }
故障排除
错误: SQLSTATE[HY000]: 一般错误:1 too many SQL variables
默认情况下,Sushi 使用 100
的块来将您的数据插入 SQLite 数据库。在某些场景中,这可能会触碰到 SQLite 的限制。您可以在模型中配置块大小: public $sushiInsertChunkSize = 50;