Last active
December 17, 2015 07:58
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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