在 Laravel 中强制执行 Morph Maps

发布于 作者

Enforcing Morph Maps in Laravel image

Oliver Nybroe 为 Laravel (8.59.0) 贡献了一个 拉取请求,允许开发人员要求设置 morph maps,而不是默认使用完全限定的类名。

通过使用 enforceMorphMap 方法而不是传统的 morphMap 方法,Laravel 将确保所有 morphs 都映射到别名,如果一个 morph 未映射,则会抛出 ClassMorphViolationException 异常。

// If any other models are morphed but not mapped, Laravel
// will throw a `ClassMorphViolationException` exception.
Relation::enforceMorphMap([
'user' => User::class,
]);

您可以使用上面显示的单个调用强制执行 morph map,也可以在 Relation 类上使用独立的 requireMorphMap 方法。

// Turn morph map enforcement on (new in 8.59.0).
Relation::requireMorphMap();
 
// And then map your morphs in the standard way.
Relation::morphMap([
'user' => User::class,
]);

Morph Map 背景

在 Laravel 中创建多态关系时,默认行为始终是在数据库中存储相关模型的类名。从 Laravel 文档

默认情况下,Laravel 将使用完全限定的类名来存储相关模型的“类型”。例如,给定上面的示例,其中 Comment 模型可能属于 Post 或 Video 模型,默认的 commentable_type 将分别为 App\Models\PostApp\Models\Video

使用此默认方法意味着您的数据库最终将填充您的模型的类名,这将您的数据库中的数据紧密地耦合到您的类的名称。

Laravel 一直以来都赋予我们通过 注册 MorphMap 来将类名与数据库分离的能力,该 MorphMap 为类提供别名,从而打破这种关联。

// Store `user` in the database, instead of `App\User`
Relation::morphMap([
'user' => User::class,
]);

虽然此行为已经存在一段时间了,但始终无法严格要求它。

Morph Maps 的优势

首先拥有 morph map 的好处是将您的应用程序逻辑与存储的数据分离。在数据库中存储类名可能会导致难以调试的错误。

如果您更改了已进行 morph 的其中一个类的名称,则数据库中的所有引用将不再与您的应用程序相符。关于这一点的棘手之处在于,开发或测试中可能没有任何东西会失败!除非您的测试套件以某种方式用先前的类名填充了您的数据库,否则您的所有测试都将是绿色的。只有当您部署到生产环境时,才会出现类和数据不匹配的问题。

上述情况可以通过编写迁移来更新存储的数据来解决,但不能保证您(或下一个用户,或下一个用户)会记得这是必需的。

与其依赖您公司的机构记忆,morph map 打破了这种关联,让您摆脱了这种潜在的错误。

强制执行 Morph Map 的优势

正如 morph map 使您不必记住在重构类时更新存储的数据一样,强制要求 morph map 使您不必记住您需要首先注册一个类。

在 morph map 可强制执行之前,开发人员或团队有责任记住首先映射 morph。

例如,一个开发人员可以像这样设置 morph map

Relation::morphMap([
'image' => Image::class,
'post' => Post::class,
]);

然后另一个开发人员可以开始使用 App\Video 作为 morph 关系,而无需将其添加到映射中!

现在,在数据库中,您将看到以下类型

  • image - 来自 morph map
  • post - 来自 morph map
  • App\Video - 来自 Laravel 默认实现

因为开发人员不知道设置了 morph map,所以他们没有注册新的 Video 模型。对于足够旧的应用程序或足够大的团队来说,这将是不可避免的。

现在通过强制执行 morph map,除非设置了别名,否则无法在 morph 中使用 App\Video。将抛出 ClassMorphViolationException

// All future morphs *must* be mapped!
Relation::enforceMorphMap([
'image' => Image::class,
'post' => Post::class,
]);

此新功能允许您将隐式知识变为显式代码要求。

我们可以使应用程序的要求越明确,随着时间的推移维护它就越容易,招募新开发人员也越容易。

Aaron Francis photo

撰写和发布有关构建产品和 Laravel 的推文。

正在开发 torchlight.devhammerstone.dev

一对龙凤胎的爸爸。

Cube

Laravel 新闻稿

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

Laravel Forge logo

Laravel Forge

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

Laravel Forge
Tinkerwell logo

Tinkerwell

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

Tinkerwell
No Compromises logo

绝不妥协

Joel 和 Aaron,来自“绝不妥协”播客的两位经验丰富的开发人员,现在可以为您的 Laravel 项目提供服务。 ⬧ 固定价格 $7500/月。 ⬧ 无需冗长的销售流程。 ⬧ 无需合同。 ⬧ 100% 退款保证。

绝不妥协
Kirschbaum logo

Kirschbaum

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

Kirschbaum
Shift logo

Shift

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

Shift
Bacancy logo

Bacancy

只需每月 $2500,就能让您的项目获得经验丰富的 Laravel 开发人员的支持,这些开发人员拥有 4-6 年的经验。获得 160 小时的专业知识和 15 天的无风险试用。立即预约通话!

Bacancy
Lucky Media logo

Lucky Media

立即获得 Lucky - 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 提示构建 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 应用程序中添加评论

阅读文章