在 Rails 中使用 Postgres UUID 时避免 PG::InvalidTextRepresentation 错误

编程入门 行业动态 更新时间:2024-10-23 19:25:04
本文介绍了在 Rails 中使用 Postgres UUID 时避免 PG::InvalidTextRepresentation 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我开始对我所有模型的 id 字段使用 Postgres UUID 类型.效果很好,并且(大部分)在 Rails 4 中得到支持:

I started using Postgres UUID type for all my models' id fields. Works great and is supported (for the most part) in Rails 4:

create_table :users, id: :uuid do |t| # ... end

问题在于,如果您尝试查找 id 为 X 的行,但 X 不是格式正确的 UUID 字符串,则 Postgres 将引发错误.

The problem is that Postgres will raise an error if you attempt to find a row where id is X, but X is not a properly formatted UUID string.

> User.find "3ac093e2-3a5e-4744-b49f-117b032adc6c" ActiveRecord::RecordNotFound # good, will cause a 404 > User.find "foobar" PG::InvalidTextRepresentation: ERROR # bad, will cause a 500

因此,如果我的用户在 URL 中包含 UUID 的页面上,然后他们尝试更改 UUID,他们将收到 500 错误而不是 404.或者他们可能会获得指向不存在的对象的链接不再存在.

So if my user is on a page where a UUID is in the URL, and they then try to change the UUID, they'll get a 500 error instead of 404. Or perhaps they get a link to an object that no longer exists.

我怎样才能以一种干燥的方式避免这种情况?我不能只是拯救 PG::InvalidTextRepresentation 并渲染 404 因为 其他事情 也可能导致此错误.

How can I go about avoiding this scenario in a DRY way? I can't just rescue the PG::InvalidTextRepresentation and render 404 because other things can cause this error as well.

更新

我认为关于 ID 参数格式的正则表达式是干净的,如果不匹配,它会引发 404:

I think that a regex on the format of the ID param is clean, and it raises a 404 if it doesn't match:

resources :users, id: /uuid-regex-here/

但我仍然有保持干燥的问题;我不想把它放在我的路线中的每一个资源上.我可以在一个语句中声明多个资源,但前提是没有其他选项(如成员操作).所以也许更好的问题是:有没有办法为所有路由设置 id 正则表达式?

But I still have the problem of staying DRY; I don't want to put this on every single resource in my routes. I can declare multiple resources in one statement, but only if don't other options to it like member actions. So perhaps a better question is: Is there a way to set the id regex for all routes?

推荐答案

您可以通过 constraints() do ... end 一次向多条路由添加路由约束.

You can add a routing constraint to multiple routes at a time via constraints() do ... end.

我最终这样做并在所有 :id 参数上设置了全局约束以将其与 UUID 正则表达式匹配:

I ended up doing this and setting a global constraint on all :id params to match it to a UUID regexp:

MyApp::Application.routes.draw do constraints(id: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i) do # my routes here end end

这样,/posts/123 或/posts/foobar 在调用控制器动作之前不再匹配/posts/:id 和 404,从而避免 PG 类型错误.

This way, /posts/123 or /posts/foobar no longer match /posts/:id and 404 before ever invoking the controller action, thus avoiding the PG type error.

我所有的模型都将使用 UUID 作为它们的 ID,所以这是干净和干燥的.如果我也有一些带有整数 ID 的模型,它会不那么干净.

All of my models will use UUID for their IDs so this is clean and DRY. If I had some models with integer IDs as well, it'd be a little less clean.

更多推荐

在 Rails 中使用 Postgres UUID 时避免 PG::InvalidTextRepresentation 错误

本文发布于:2023-10-17 10:33:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1500660.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:错误   Postgres   Rails   UUID   InvalidTextRepresentation

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!