Skip to content

Instantly share code, notes, and snippets.

@twolfson
Created June 12, 2018 02:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save twolfson/8e981af620c51d149e92054ea92fa89f to your computer and use it in GitHub Desktop.
Save twolfson/8e981af620c51d149e92054ea92fa89f to your computer and use it in GitHub Desktop.
Rails acts-as-keyed updated/simplified
# Largely based on `acts-as-keyed` but with less magic (namely make `to_param` consistent, don't overwrite `find`)
# https://github.com/jhubert/acts-as-keyed
# http://vaidehijoshi.github.io/blog/2015/10/13/stop-worrying-and-start-being-concerned-activesupport-concerns/
module KeyedModel
extend ActiveSupport::Concern
KEY_CREATION_RETRIES = 100
KEY_LENGTH = 8
included do
if ActiveRecord::Base.connection.table_exists?(self.table_name) && columns_hash["key"].nil?
raise "Missing `key` column. Please ensure it was added in a migration via generator (easiest for UNIQUE index)"
end
before_validation(:create_key, :on => :create)
end
class_methods do
# DEV: We don't extend `find` so we don't back ourselves into a corner with type inference
# An example failure would be moving to UUIDs which are also string based
# it would make a lot of replacements for `find` or add computation complexity
def key_exists?(key_val)
return exists?(:key => key_val)
end
def generate_key()
# http://api.rubyonrails.org/classes/SecureRandom.html
# A-Z, a-z, 0-9 except for visually similar characters (i.e. 0 vs O, I vs l)
return SecureRandom.base58(KEY_LENGTH)
end
def from_param(param)
return find_by_key!(param)
end
end
def to_param
return self.key
end
protected
def create_key
key_val = nil
KEY_CREATION_RETRIES.times do
key_val = self.class.generate_key()
break if not self.class.key_exists? key_val
key_val = nil
end
if key_val.nil?
raise "Could not find unique key in #{KEY_CREATION_RETRIES} tries. Please expand `key` size for #{self.class.name}"
end
self.key = key_val
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment