在创建一个给定的ActiveRecord模型对象的实例时,我需要生成一个简短的(6-8个字符)唯一字符串,作为URL中的标识符,使用Instagram的照片URL(如http://instagram.com/p/P541i4ErdL/,我刚刚拼凑成404)或Youtube的视频URL(如http://www.youtube.com/watch?v=oHg5SJYRHA0)的样式。
做这件事最好的方法是什么?重复使用create a random string直到它是唯一的,这是最简单的吗?有没有办法散列/混洗整数id,使用户不能通过更改一个字符来破解URL (就像我对上面的404'd Instagram链接所做的那样),并以新的记录结束?
发布于 2012-09-26 00:32:23
你可以这样做:
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
发布于 2012-09-25 10:15:21
您可以对id进行散列:
Digest::MD5.hexdigest('1')[0..9]
=> "c4ca4238a0"
Digest::MD5.hexdigest('2')[0..9]
=> "c81e728d9d"
但仍然有人可以猜到你在做什么,并以这种方式迭代。对内容进行散列可能会更好
https://stackoverflow.com/questions/12575022
复制相似问题