You can add a routing constraint to multiple routes at a time via constraints() do ... end
.
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
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.
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.