Skip to content

Instantly share code, notes, and snippets.

@audionerd
Last active December 17, 2015 07:58
Show Gist options
  • Save audionerd/5576583 to your computer and use it in GitHub Desktop.
Save audionerd/5576583 to your computer and use it in GitHub Desktop.
A minimal re-usable module for "token" slugs on ActiveRecord models (AKA shortcodes, tiny urls)
# token.rb
# A minimal re-usable module for "token" slugs on ActiveRecord models (AKA shortcodes, tiny urls)
#
# USAGE
#
# class Project < ActiveRecord::Base
# include Token
# end
#
# see also:
# http://stackoverflow.com/questions/6169541/rails-3-1rc1-to-param-from-param-without-effect
# https://github.com/citrus/spree_mail/blob/master/lib/spree_mail/has_token.rb
# https://github.com/bbommarito/token_generator/blob/master/lib/token_generator.rb
# related gems: stringex, friendlyid
require 'securerandom'
module Token
extend ActiveSupport::Concern
included do
validates :token, presence:true, uniqueness:true
before_validation :set_token, on: :create
end
module ClassMethods
# via http://tomafro.net/2009/09/tip-the-case-for-from-param
def from_param(param)
self.where( token: param ).first
end
end
def to_param
self.token
end
private
def generate_token
# keep generating tokens until one is unique
token = nil
loop do
token = SecureRandom.random_number(36**5).to_s(36)
break if self.class.from_param(token).nil?
end
token
end
def set_token
self.token ||= generate_token
end
end
require 'active_support'
require 'active_record'
require './token'
ActiveRecord::Base.establish_connection(
:adapter => 'sqlite3',
:database => 'test_token.sqlite3.db'
)
begin
ActiveRecord::Schema.define do
create_table :projects do |t|
t.string :name
t.string :token
end
end
rescue ActiveRecord::StatementInvalid
# Do nothing - schema already exists
end
class Project < ActiveRecord::Base
include Token
end
@project = Project.create!
@project.to_param == @project.token
Project.from_param(@project.to_param) == @project
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment