预处理控制器方法的模型类型提示路由参数中的主键

Posted

技术标签:

【中文标题】预处理控制器方法的模型类型提示路由参数中的主键【英文标题】:Preprocessing primary keys in a controller method's model type hinted route parameter 【发布时间】:2021-05-28 19:00:38 【问题描述】:

我有一些模型使用自定义的非顺序唯一 ID,类似于标准 UUID。它们是 64 位长,应该可以使用 8000 多年,所以我将它们存储为无符号大整数。

但是,作为 base10 数字,它们在 19 位时有点长且笨拙。为了帮助解决这个问题,我可以将它们转换为 base36 数字(包含 0-9 和 a-z 的字符串)。它们最多 15 个字符,但在接下来的 30 年左右应该只有 11 或 12 个字符。

我的问题是是否有办法挂钩到 Laravel 的类型提示依赖注入,以便这样的构造方法:

public function show(ModelName $modelName) 
    dump($modelName);

使用标准资源路由:

Route::get('modelName/modelName', 'ModelController@show');

使用 base36 字符串调用时将返回正确的模型

【问题讨论】:

【参考方案1】:

如果我理解正确,路由绑定会解决你的问题:

在您的RouteServiceProvider 的启动函数中:

public function boot()

    Route::bind('modelName', function ($value) 
        return ModelName::where('name', $value)->firstOrFail();
    );

    // ...

或者,如果您想在模型级别解决它(可能带有特征),您可以覆盖模型中的 resolveRouteBinding 函数:

public function resolveRouteBinding($value, $field = null)

    return $this->where('name', $value)->firstOrFail();

来源:https://laravel.com/docs/8.x/routing#customizing-the-resolution-logic

【讨论】:

这绝对很有帮助,因为我能够在文档中链接到的位下方找到我正在寻找的内容。您的解决方案的问题是我必须为使用这种 id 的每个模型执行此操作。我最终在我应用到受影响模型的 trait 中使用了 resolveRouteBinding(实际上我已经有了 uid 的 trait)。 此外,我们能够在 trait 中重载 forwardsCallTo,以挂钩模型的 find 方法。我们正在使用的 Laravel 6 实际上只使用resolveRouteBinding 用于具有多个参数的路由,对于单个参数它只是进行查找。由于我一般只询问有关 laravel 的问题,如果您使用 resolveRouteBinding 方法更新您的答案,我愿意接受您的回答。

以上是关于预处理控制器方法的模型类型提示路由参数中的主键的主要内容,如果未能解决你的问题,请参考以下文章

出现在控制源不是 PK 字段的文本框中的记录的主键

django ORM模型常用字段字段常用参数

模型绑定不适用于 asp.net 核心 Web api 控制器操作方法中的 Stream 类型参数。(即使使用自定义流输入格式化程序)

Django:如何在urlpatterns中访问其他模型的主键?

java 控制器方法中的动态路由参数

Laravel入门使用(路由)