Generating an Instagram- or Youtube-like unguessable string ID in ruby/ActiveRecord

前端 未结 3 917
被撕碎了的回忆
被撕碎了的回忆 2020-12-09 12:12

Upon creating an instance of a given ActiveRecord model object, I need to generate a shortish (6-8 characters) unique string to use as an identifier in URLs, in the style of

3条回答
  •  Happy的楠姐
    2020-12-09 12:17

    You could do something like this:

    random_attribute.rb

    module RandomAttribute
    
      def generate_unique_random_base64(attribute, n)
        until random_is_unique?(attribute)
          self.send(:"#{attribute}=", random_base64(n))
        end
      end
    
      def generate_unique_random_hex(attribute, n)
        until random_is_unique?(attribute)
          self.send(:"#{attribute}=", SecureRandom.hex(n/2))
        end
      end
    
      private
    
      def random_is_unique?(attribute)
        val = self.send(:"#{attribute}")
        val && !self.class.send(:"find_by_#{attribute}", val)
      end
    
      def random_base64(n)
        val = base64_url
        val += base64_url while val.length < n
        val.slice(0..(n-1))
      end
    
      def base64_url
        SecureRandom.base64(60).downcase.gsub(/\W/, '')
      end
    end
    Raw
    

    user.rb

    class Post < ActiveRecord::Base
    
      include RandomAttribute
      before_validation :generate_key, on: :create
    
      private
    
      def generate_key
        generate_unique_random_hex(:key, 32)
      end
    end
    

提交回复
热议问题