In some situations it's ideal to be able to hide the ID number in a database table. Here's how to do it using Crystal Amber and the Granite ORM.
Create your model
amber g model WebLink url:string
Edit the migration file to use either a VARCHAR
or UUID
if it supports it (Hint: Postgres does!). To use a hex string instead, stick with VARCHAR
.
-- +micrate Up
CREATE TABLE web_links (
id UUID PRIMARY KEY,
url VARCHAR,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
-- +micrate Down
DROP TABLE IF EXISTS web_links;
Edit the model file to include the UUID
library, set the Primary Key as a string and turn off auto increment. Then add the before_create
macro to assign a new UUID
on creation.
require "uuid"
class WebLink < Granite::Base
adapter pg
table_name web_links
# id : Int64 primary key is created for you
primary id : String, auto: false
field url : String
timestamps
before_create :assign_id
def assign_id
@id = UUID.random.to_s
end
end
Alternatively, use UUID.random.hexstring.to_s
for an alternate style (e.g. 2d10e1a2fa89425197d62f94c6cf07dc
). The UUID
database data type will convert this automatically so make sure to set the data type to VARCHAR
.
To use shorter IDs chop the hexstring
down by using the range syntax [0..6]
, replacing 6 with the desired length, and then check for duplicates before creating the table row.
def assign_id
potential_id = UUID.random.hexstring.to_s[0..6]
while WebLink.find(potential_id)
potential_id = UUID.random.hexstring.to_s[0..6]
end
@id = potential_id
end
That's it! Make sure to run crystal db migrate
before running the application.