A different way to do this would be to use the default IDs as provided, but then add a dedicated column using a UUID when you need public (non-secured) access to the item.
I think this would work pretty well:
class Widget {
String uuid
static constraints = {
uuid unique: true
}
def beforeInsert() {
// optionally, replace the dashes by adding .replaceAll('-','')
uuid = UUID.randomUUID().toString()
}
}
Then you could use a controller like so:
// url: app/public/widget/48b5451a-0d21-4a36-bcc0-88b129852f1b
PublicController {
def widget() {
Widget w = Widget.findByUuid(params.id)
...
}
}
This is indexed automatically, so it's not too slow, and the UUID is only used when looking up the widget publicly. If you have a person logged in, then you can perform security checks, and just use app/widget/edit/1
or something similar.
I wouldn't rely on a "random number" as being secure by any means. Guessing numbers works even if the numbers are not sequential. Guessing a UUID is next to impossible, comparatively. However, if you have accounts with a login, authorization checks are best by far.