学习 Laravel Sushi - Eloquent 的数组驱动

发布时间:作者:

Learn Laravel Sushi - The array driver for Eloquent image

上周,我发布了一篇文章 使用 Volt 和 Folio 构建示例应用程序。在这个例子中,我使用了 Caleb Porzio 的包,Sushi,来模拟一些示例数据。这让我对其他人使用 Sushi 做了什么感到好奇,所以我 发推 询问人们他们使用它的目的。在这篇文章中,我们将介绍 Sushi 的基本概念以及一些关于如何使用它的示例。

什么是 Laravel Sushi,它是如何工作的?

根据该包的 README 文档,Sushi 是“Eloquent 缺少的“数组”驱动程序。”换句话说,它允许您从除数据库以外的数据源创建 Eloquent 模型。最简单的使用方法是在 Model 文件中直接提供数据作为硬编码数组,并设置 $rows 属性。其他时候,您可以使用 getRows 来提供动态数据 - 来自 API 源、CSV 文件或您选择的任何其他地方。

那么它到底是如何工作的呢?Sushi 会获取您提供的数据,创建 Eloquent 模型,然后将它们缓存到 SQLite 数据库中。然后,您可以像查询任何标准 Eloquent 模型一样查询数据。

以下是一个非常基本的 Sushi 模型示例

<?php
 
namespace App\Models;
 
use Sushi\Sushi;
 
class Role extends Model
{
// Add the trait
use Sushi;
 
// Provide the data as a hardcoded array
protected $rows = [
['id' => 1, 'label' => 'admin'],
['id' => 2, 'label' => 'manager'],
['id' => 3, 'label' => 'user'],
];
}

Laravel Sushi 州

让我们深入了解一些我和其他人使用过的真实示例。我将介绍的最基本的一个是创建州列表或表格。 KenFacundo 提到了这个用例,但我本人也使用过。

<?php
 
namespace App\Models;
 
use Sushi\Sushi;
 
class Role extends Model
{
use Sushi;
 
protected $rows = [
[
'id' => 1,
'name' => 'Alabama',
'abbreviation' => 'AL',
],
[
'id' => 2,
'name' => 'Alaska',
'abbreviation' => 'AK',
],
[
'id' => 3,
'name' => 'Arizona',
'abbreviation' => 'AZ',
],
[
'id' => 4,
'name' => 'Arkansas',
'abbreviation' => 'AR',
],
[
'id' => 5,
'name' => 'California',
'abbreviation' => 'CA',
],
// ...
];
}

注意:'id' 列是可选的。Sushi 可以为每个项目创建自动递增的 ID,但如果项目发生更改(并且缓存被清除),您不能保证项目会获得与之前相同的 ID。如果您要将其他数据与 Sushi 模型关联,最好为每个项目提供一个静态 ID 列。

Laravel Sushi 用于博客、课程和信息产品

另一个方便的用例是用于简单的博客和课程。有时,作为一名开发人员,我需要为博客或课程存储一些页面,但我不需要完整的 CMS。我宁愿保持轻量级,同时将所有内容直接存储在代码中,以便可以通过 Git 同步。

Aaron 提到了他使用这种设置来构建 aaronfrancis.com 上的博客。 Caleb 提到了 Livewire v2 演示平台使用了类似于此的功能

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Sushi\Sushi;
 
class Series extends Model
{
use Sushi;
 
public function screencasts()
{
return $this->hasMany(Screencast::class);
}
 
public function getRows()
{
return [
['id' => 1, 'order' => 1, 'title' => 'Getting Started'],
['id' => 2, 'order' => 2, 'title' => 'A Basic Form With Validation'],
//...
];
}
}
<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Sushi\Sushi;
 
class Screencast extends Model
{
use Sushi;
 
public function series()
{
return $this->belongsTo(Series::class);
}
 
public function getNextAttribute()
{
return static::find($this->id + 1);
}
 
public function getPrevAttribute()
{
return static::find($this->id - 1);
}
 
public function getDurationInSecondsAttribute()
{
// ...
}
 
protected $rows = [
[
'title' => 'Installation',
'slug' => 'installation',
'description' => "Installing Livewire is so simple, this 2.5 minute video feels like overkill. Composer require, and two little lines added to your layout file, and you are fully set up and ready to rumble!",
'video_url' => 'https://vimeo.com/...',
'code_url' => 'https://github.com/...',
'duration_in_minutes' => '2:32',
'series_id' => 1,
],
[
'title' => 'Data Binding',
'slug' => 'data-binding',
'description' => "The first and most important concept to understand when using Livewire is "data binding". It's the backbone of page reactivity in Livewire, and it'll be your first introduction into how Livewire works under the hood. Mandatory viewing.",
'video_url' => 'https://vimeo.com/...',,
'code_url' => 'https://github.com/...',
'duration_in_minutes' => '9:11',
'series_id' => 1,
],
// ...
];
}

如您在此示例中看到的,由于这些是真正的 Eloquent 模型,因此您可以添加关系、getter 和辅助方法,就像您在普通模型上一样。

有了这些模型,您可以在控制器或 Livewire 组件中查询它们,就像查询数据库驱动的模型一样

$series = Series::with(['screencasts'])->orderBy('order')->get();

然后,您可以在 Blade 中循环遍历它们

<div>
@foreach($series as $s)
<div>
<h2>{{ $series->title }}</h2>
<div>
@foreach($series->screencasts as $screencast)
<div>
<h3>{{ $screencast->title }}</h3>
<p>{{ $screencast->description }}</p>
</div>
@endforeach
</div>
</div>
@endforeach
</div>

您甚至可以使用 Laravel 的路由模型绑定自动查询 Sushi 模型

Route::get('/screencasts/{screencast:slug}');

Caleb 和我使用非常相似的方法来存储 Alpine Components 的组件。我们使用路由模型绑定进行路由,然后使用 Blade 视图显示每个组件的详细信息。

在 Blade 视图中,我们循环遍历组件的变体并使用 @include($variant->view) 来包含单独的硬编码 Blade 视图,其中包含组件的实际代码。

<?php
 
namespace App\Models;
 
use App\Enums\ComponentType;
use Illuminate\Database\Eloquent\Model;
use Sushi\Sushi;
 
class Component extends Model
{
use Sushi;
 
protected $casts = [
'variants' => 'collection',
'requirements' => 'collection',
'type' => ComponentType::class,
];
 
public function getRows()
{
return [
[
'title' => 'Dropdown',
'slug' => 'dropdown',
'description' => 'How to build a dropdown component using Alpine.js.',
'screencast_id' => 111,
'variants' => json_encode([
['view' => 'patterns.dropdown'],
]),
'type' => ComponentType::COMPONENT->value,
'is_public' => true,
'is_free' => true,
'requirements' => json_encode([
[
'name' => 'alpinejs',
'version' => 'v3.x',
'url' => 'https://alpinejs.dev/installation',
],
 
]),
],
[
'title' => 'Modal',
'slug' => 'modal',
'description' => 'How to build a modal component using Alpine.js.',
'screencast_id' => 222,
'variants' => json_encode([
['view' => 'patterns.modal'],
]),
'type' => ComponentType::COMPONENT->value,
'is_public' => true,
'is_free' => false,
'requirements' => json_encode([
[
'name' => 'alpinejs',
'version' => 'v3.x',
'url' => 'https://alpinejs.dev/installation',
],
[
'name' => '@alpinejs/focus',
'version' => 'v3.x',
'url' => 'https://alpinejs.dev/plugins/focus',
],
]),
],
// ...
];
}
}

如您在此示例中看到的,我们使用了 getRows 方法,而不是设置 $rows 属性。这是为了我们可以使用 json_encode() 函数,并为每个模型的 variantsrequirements 列使用 JSON 列。您还可以看到,Sushi 支持将属性转换为不同的类型,就像 Laravel 一样。

API 数据源

另一个不错的用例是从 API 源获取数据。 RaúlMarcelAdam 和 Caleb 提到了他们使用过的不同的 API 源。

Caleb 向 GitHub Sponsors API 发送请求以确定谁可以访问 Livewire v2 演示,然后映射这些结果以获取他需要的属性并将其格式化为模型的良好模式。这是 Livewire v2 代码库中 Sponsor 模型的简化版本

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Sushi\Sushi;
 
class Sponsor extends Model
{
use Sushi;
 
protected $keyType = 'string';
 
public function user()
{
return $this->hasOne(User::class, 'github_username', 'username');
}
 
public function getsScreencasts()
{
// If they sponsor for more than $8, they get access to screencasts.
return $this->tier_price_in_cents > 8 * 100;
}
 
public function getRows()
{
return Cache::remember('sponsors', now()->addHour(), function () {
return collect($this->fetchSponsors())
->map(function ($sponsor) {
return [
'id' => $sponsor['sponsorEntity']['id'],
'username' => $sponsor['sponsorEntity']['login'],
'name' => $sponsor['sponsorEntity']['name'],
'email' => $sponsor['sponsorEntity']['email'],
// ...
];
});
});
}
 
public function fetchSponsors()
{
return Http::retry(3, 100)
->withToken(
config('services.github.token')
)->post('https://api.github.com/graphql', [
'query' => 'A big ugly GraphQL query'
]);
}
}

结论

Sushi 是一个非常棒的包,有一些很棒的用例。我相信在这篇文章中我只触及了表面。如果您使用过这个包,请在 Twitter 上告诉我您的使用体验!

Jason Beggs photo

TALL 技术栈(Tailwind CSS、Alpine.js、Laravel 和 Livewire)顾问和 designtotailwind.com 的所有者。

归档于
Cube

Laravel 时事通讯

加入 40,000 多名其他开发人员,不错过任何新技巧、教程等。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动完成和对本地和生产环境的即时反馈进行调试。

Tinkerwell
No Compromises logo

无妥协

Joel 和 Aaron,来自 No Compromises 播客的两位经验丰富的开发人员,现已可供您的 Laravel 项目聘用。 ⬧ 固定费率为每月 7,500 美元。 ⬧ 无需冗长的销售流程。 ⬧ 无需合同。 ⬧ 100% 退款保证。

无妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,确保您的 Web 应用程序取得成功。

Kirschbaum
Shift logo

Shift

运行旧版本的 Laravel?即时、自动化的 Laravel 升级和代码现代化,让您的应用程序焕然一新。

Shift
Bacancy logo

Bacancy

只需每月 2,500 美元,即可为您的项目配备经验丰富的 Laravel 开发人员,拥有 4-6 年的经验。获得 160 小时的专业知识和 15 天的免费试用期。立即预约电话!

Bacancy
Lucky Media logo

Lucky Media

现在就幸运 - Laravel 开发的理想选择,拥有十多年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel 电子商务

适用于 Laravel 的电子商务。一个开源包,将现代无头电子商务功能的强大功能带到 Laravel。

Lunar: Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 招聘网站

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS 启动套件

SaaSykit 是一个 Laravel SaaS 启动套件,包含运行现代 SaaS 所需的所有功能。支付、漂亮的结账、管理面板、用户仪表盘、身份验证、现成组件、统计信息、博客、文档等等。

SaaSykit: Laravel SaaS 启动套件
Rector logo

Rector

您无缝升级 Laravel、降低成本和加速创新的合作伙伴,助您取得成功。

Rector
MongoDB logo

MongoDB

通过将 MongoDB 和 Laravel 强力整合,提升您的 PHP 应用程序,赋予开发者轻松高效地构建应用程序的能力。在使用熟悉的 Eloquent API 的同时,支持事务、搜索、分析和移动用例。探索灵活的现代数据库 MongoDB 如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单、零依赖的输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel Prompts 构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包向您的 Laravel 应用程序添加评论

阅读文章