在创建给定的ActiveRecord模型对象的实例时,我需要生成一个短(6-8个字符)的唯一字符串,用作URL中的标识符,以Instagram的照片URL的形式(如
http://instagram.com/p/P541i4ErdL/,我刚刚加入一个404)或Youtube的视频网址(如
http://www.youtube.com/watch?v=oHg5SJYRHA0).
做这个的最好方法是什么?直到create a random string才是最简单的,直到它独特吗?有没有办法以整数的方式进行hash / shuffle,使得用户不能通过改变一个字符来篡改URL(就像我之前用404的“Instagram”链接一样),最后是一个新的记录?
解决方法
你可以这样做:
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,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