解锁 Laravel 代码生成(第 3 部分):从数据库架构中自动验证

为什么要实现代码生成自动化?
手动编写代码,尤其是像CRUD(创建、读取、更新、删除)和验证这类样板代码,既耗时又重复,还容易出现人为错误。将自动化融入工作流程后,你将获得以下好处:
- 保持同步:无论何时在数据库中添加或删除列,只需一个命令就能重新生成代码。
- 提高一致性:每个生成的文件都遵循统一的结构和编码标准。
- 减少人工劳动:将精力集中在应用程序的独特功能上,而不是重复的任务。
- 节省时间:在添加或修改列时减少重复的样板代码。
提取数据库模式
实现自动化的第一步是提取数据库模式。我们要将表定义转换为JSON文件,这种格式易于阅读、修改,并且方便用于代码生成过程。
将模式提取为JSON
第一步是将表信息(如列和索引)提取到一个JSON文件中。以下是一段简短的代码片段(来自我在较大项目中使用的TableUtils类,关注我以获取未来项目及更新信息!),展示了如何获取给定表的列信息:
// TableUtils代码片段
public function getTableInfo(): Collection
{
// 确保表存在
if (!Schema::hasTable($this->table)) {
throw new \Exception("表 {$this->table} 未找到");
}
$columns = Schema::getColumns($this->table);
return collect([
'model' => Str::studly(Str::singular($this->table)),
'table' => $this->table,
'columns' => $columns,
]);
}
然后,将这个集合转换为JSON并保存到一个文件中,比如schema/categories.json。(这样就无需每次都进行查询)
{
"model": "Category",
"table": "categories",
"columns": [
{
"name": "id",
"type": "bigint(20) unsigned",
"nullable": false
},
{
"name": "name",
"type": "varchar(255)",
"nullable": false
},
{
"name": "created_at",
"type": "timestamp",
"nullable": true
},
{
"name": "updated_at",
"type": "timestamp",
"nullable": true
}
]
}
最小化表单请求存根
接下来,我们创建一个表示Laravel中表单请求的小存根,这是我们在第一部分学到的内容:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class Store{{modelName}}Request extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
{{validationRules}}
];
}
}
自动生成验证规则
这里有一个小命令,它读取JSON文件,分析每一列,并将适当的验证规则注入到存根中,这是我们在第二部分学到的将存根和命令结合的方法:
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class GenerateValidation extends Command
{
protected $signature = 'generate:validation {table}';
protected $description = '从表模式JSON生成表单请求验证文件';
public function handle()
{
$table = $this->argument('table');
$schemaPath = base_path("schema/{$table}.json");
if (! File::exists($schemaPath)) {
$this->error("表 [{$table}] 的模式JSON在以下路径未找到: {$schemaPath}");
return;
}
// 加载模式
$schema = json_decode(File::get($schemaPath), true);
// 加载我们的存根
$validationStub = File::get(base_path('stubs/validation.stub'));
// 根据列构建规则
$rules = collect($schema['columns'])->map(function ($column) {
$ruleParts = [];
// 必填或可为空
$ruleParts[] = $column['nullable']? 'nullable' :'required';
// 字符串的简单示例
if (preg_match('/varchar\((\d+)\)/', $column['type'], $matches)) {
$maxLength = $matches[1];
$ruleParts[] ='string';
$ruleParts[] = "max:{$maxLength}";
}
// 可以针对其他类型(如整数、日期)进行扩展
return "'{$column['name']}' => '". implode('|', $ruleParts). "'";
})->implode(",\n ");
// 将规则插入存根
$validationStub = str_replace('{{modelName}}', $schema['model'], $validationStub);
$validationStub = str_replace('{{validationRules}}', $rules, $validationStub);
// 保存到app/Http/Requests目录
$filename = "Store{$schema['model']}Request.php";
File::put(app_path("Http/Requests/{$filename}"), $validationStub);
$this->info("为 [{$schema['model']}] 创建的验证文件: {$filename}");
}
}
它的工作原理如下:
- 加载JSON:我们获取表的模式文件(例如categories.json)。
- 解析列:分析每一列,查看它是否可为空或是否为varchar(x)类型。
- 构建规则字符串:例如,一个不可为空的varchar(255)将变为required|string|max:255。
- 注入到存根:占位符{{validationRules}}被替换为构建好的规则字符串。
- 生成文件:最终生成的StoreCategoryRequest.php文件可在Laravel应用程序中使用。
为什么这很重要
- 节省时间:你再也无需手动输入required|string|max:255这类内容。
- 防止错误:对数据库的更改只需一键操作就能同步到验证规则中。
- 易于扩展:添加针对整数、日期或枚举的逻辑,无论哪种适合你的模式。
展望未来
这只是冰山一角。一旦你熟悉了模型、控制器和验证的自动化,你可以进一步扩展到:
- 视图生成:使用你的模式生成用于列出、创建、编辑和查看记录的Blade模板。
- API资源:根据你的模式自动构建API控制器、路由和资源类。
- 关系:整合外键数据以自动生成hasOne、hasMany、belongsTo等关系。
目前,这里概述的方法为自动化Laravel开发工作流程的大部分内容提供了强大的基础。
结论
通过利用数据库模式生成验证规则,你朝着完全自动化的代码生成管道又迈进了一步。你可以应用相同的原则来构建模型、控制器等,从而获得一个健壮、可扩展且易于维护的开发过程。
要点总结
- 集中验证:使表单请求始终与实际数据库保持一致。
- 尽量减少手动维护:每当列发生变化时重新生成,让脚本完成繁重的工作。
- 根据需要扩展:随着应用程序的增长,为更多数据类型(如整数、小数、日期)添加规则。
通过这种设置,你再也无需在多个地方跟踪列的变化,数据库模式成为唯一的事实来源。祝编码愉快,愿你的所有验证都准确无误!
Publish on 2025-01-09,Update on 2025-02-10