我试图找到一种方法来完成这项任务:
- >每当'" Sale"保存到DB rails必须生成一个哈希值(不超过250个字符)并将值保存到列#34;令牌"。
我经常搜索,但没有达到我的要求。你有什么想法吗?
提前致谢!
答案 0 :(得分:3)
我对此类事情的追求是SecureRandom.hex
。它需要一个指示长度的参数 - 例如。在你的情况下SecureRandom.hex(250)
。它是十六进制 - 所以使用数字,然后是字母a-f。
我想你也希望它在你的数据库中的所有记录中都是唯一的?如果是这样,你会在你的模型中想要这样的东西:
def generate_unique_token
loop do
token = SecureRandom.hex
break token unless self.class.exists?(token: token)
end
end
答案 1 :(得分:2)
添加到其他人的答案... Rails 5有一个has_secure_token
方法,你可以简单地添加到你的ActiveRecord类,例如,
class User < ActiveRecord::Base
has_secure_token
end
这种方法基本上可以完成其他人建议你做的肮脏工作。如果您还没有使用Rails 5,那么可以使用Rails 4 backport:
答案 2 :(得分:1)
class Sale < ActiveRecord::Base
before_save :generate_token
def generate_token(length=250)
self.token = [*('A'..'Z'),*('a'..'z'),*('0'..'9')].sample(length).join
end
end
你可以控制长度和角色。
答案 3 :(得分:1)
建立在富裕的回答之上:
class Sale < ActiveRecord::Base
before_save :generate_token
validates :token, uniqueness: true
def generate_token(length=50)
self.token = SecureRandom.urlsafe_base64(length, false)
end
end
唯一性可通过validation确保。
修改强>
上面的验证是无用的,并且在生成的令牌不唯一时无法解决问题。需要一个循环(就像joshua.paling提出的那样),或者更好地使用has_secure_token
(由Mike Desjardins提出)implements类似的东西。最重要的是,我们鼓励您在数据库中添加唯一索引以避免竞争条件:
class Sale < ActiveRecord::Base
before_create :generate_token
def generate_token(length=50)
loop do
token = self.token = SecureRandom.urlsafe_base64(length, false)
break token unless self.class.exists?(token: token)
end
end
end
编辑“验证”