Using UUIDs with Crystal Amber

Mitch

Warning - Old content ahead!

This page has been marked as a legacy post. This means it's quite old (from 2018) and probably out of date. Take it with a grain of salt!

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.

Spread the word

Share this article

Like this content?

Check out some of the apps that I've built!

Snipline

Command-line snippet manager for power users

View

Pinshard

Third party Pinboard.in app for iOS.

View

Rsyncinator

GUI for the rsync command

View

Comments