How does Stripe generate object ids?
Patrick Collison, Stripe CEO:
They're randomly generated by our Ruby application code. We use the
ch_
-style prefixes because we find it really useful to be able to immediately recognize the type of an ID when looking at logs or stacktraces.
With PrettyId you can generate Stripe-like IDs for your ActiveRecord models:
charge.id #=> ch_xxx
user.id #=> usr_xxx
transaction.id #=> txn_xxx
For each model when you create table inside migration, you have to:
- tell AR to not automatically add primary key column.
- create
id
column as string - add unique index for
id
column
create_table :users, id: false do |t|
t.string :id, null: false
# your other columns
end
add_index(:users, :id, unique: true)
Inside model class just include PrettyId module:
class User < ActiveRecord::Base
include PrettyId
end
By default first 3 letters of model class will be taken as id prefix. You can change it by specifying your own value:
class User < ActiveRecord::Base
include PrettyId
self.id_prefix = 'usr'
end
Or, if you want to add some tricky logic for id prefix (let's say for test account it should be acc_test
and for live account it should be acc_live
) you can provide a Proc that will return id prefix:
class Account < ActiveRecord::Base
include PrettyId
attr_accessor :type
self.id_prefix = -> (model) { model.type == 'test' ? 'acc_test' : 'acc_live' }
end
account = Account.new
account.type = 'test'
account.save
account.id #=> acc_test_....
For cases when you don't want underscore (_) to be in id you can set it to nil:
class User < ActiveRecord::Base
include PrettyId
self.id_prefix = 'usr'
self.id_separator = nil
end
user.id #=> usrPZUjZiIF3bnZ
Note There is another gem called 'pretty_id' so I had to rename mine into prettyid. So, be careful when you install gem and require it. It's a kind'a trick you do with 'activerecord' as well ;)
Add this line to your application's Gemfile:
gem 'prettyid', require: 'pretty_id'
And then execute:
$ bundle
Or install it yourself as:
$ gem install prettyid
If you care about performance, it's better to measure it yourself :) I have measured method that generates id (rake bm
). Here are results for 1M calls:
user system total real
PrettyId::Generator#id: 12.880000 0.020000 12.900000 ( 12.907587)
Bug reports and pull requests are welcome on GitHub at https://github.com/alovak/pretty_id.
This code is available under MIT license.
© Pavel Gabriel, 2018