BasedUUID: URL-friendly UUIDs for Rails models
Generate “double-clickable”, URL-friendly UUIDs with optional prefixes:
user_763j02ryxh8dbs56mgcjqrmmgt #=> e61c802c-7bb1-4357-929a-9064af8a521a
bpo_12dm1qresn83st62reqdw7f7cv #=> 226d037c-3b35-40f3-a30b-0ebb78779d9b
This gem encodes UUID primary keys into 26-character lowercase strings using Crockford’s base32 encoding. The optional prefix helps you identify the model it represents.
By default, BasedUUID assumes that you have a UUID primary key (id
) in your ActiveRecord model. It doesn’t affect how UUIDs are stored in the database. Prefixes and base32-encoded strings are only used for presentation.
Installation
Add this line to your Gemfile
:
gem "based_uuid"
Usage
Add the following line to your model class:
class BlogPost < ApplicationRecord
has_based_uuid prefix: :bpo
end
post = BlogPost.last
post.based_uuid
post.based_uuid(prefix: false)
post.based_uuid_with_prefix
post.based_uuid_without_prefix
Lookup
BasedUUID includes a find_by_based_uuid
model method to look up records:
BlogPost.find_by_based_uuid("bpo_12dm1qresn83st62reqdw7f7cv")
BlogPost.find_by_based_uuid("12dm1qresn83st62reqdw7f7cv")
BlogPost.find_by_based_uuid!("12dm1qresn83st62reqdw7f7cv")
Generic lookup
The gem provides a generic lookup method to help you find the correct model for the UUID, based on prefix:
BasedUUID.find("bpo_12dm1qresn83st62reqdw7f7cv")
BasedUUID.find("user_763j02ryxh8dbs56mgcjqrmmgt")
⚠️ NOTE: Rails lazy-loads models in the development environment, so this method won’t know about your models until you’ve referenced them at least once. If you’re using this method in a Rails console, you’ll need to run BlogPost
(or any other model) before you can use it.
BasedUUID as default URL identifiers
BasedUUID aims to be non-intrusive and it doesn’t affect how Rails URLs are generated, so if you want to use it as default URL param, add this to your model:
def to_param
based_uuid
end
Custom UUID column name
BasedUUID
will respect the value of Model.primary_key
, so it supports custom primary key names:
class Transaction < ApplicationRecord
self.primary_key = "txid"
has_based_uuid prefix: :tx
end
If you want to use a different column, other than the primary key, you can pass it as an option to has_based_uuid
:
class Session < ApplicationRecord
has_based_uuid prefix: :sid, uuid_column: :session_id
end
Use outside ActiveRecord
BasedUUID can be used outside ActiveRecord, too. You can encode any UUID with it:
BasedUUID.encode(uuid: "226d037c-3b35-40f3-a30b-0ebb78779d9b")
BasedUUID.encode(uuid: "226d037c-3b35-40f3-a30b-0ebb78779d9b", prefix: :bpo)
BasedUUID.decode("bpo_12dm1qresn83st62reqdw7f7cv")
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/pch/based_uuid.
Credits
This gem is heavily inspired by Stripe IDs and the prefixed_ids gem by Chris Oliver.
Parts of the base32 encoding code are borrowed from the ulid gem by Rafael Sales.