我将每个已创建项目的唯一代码归因于在URL中使用。我在模型中创建项目时执行此操作:
class Item < ActiveRecord::Base
before_create { self.code = SecureRandom.urlsafe_base64 }
end
但我不知道生成的代码是否真的是唯一的。我是否必须在创建期间检查唯一性,但如果Items表增长,这可能会花费不必要的时间和资源:
before_create :generate_unique_code
def generate_unique_code
loop do
code = SecureRandom.urlsafe_base64
unless Item.where(:code => code).any?
self.code = code
break
end
end
end
我可以相信SecureRandom.urlsafe_base64
的唯一性并跳过检查吗?
答案 0 :(得分:1)
计算机生成的字符串中没有任何内容是完全随机的。从技术上讲,两个字符串可能相同的可能性非常低。
在高度并发的系统中更是如此。如果情况并非如此,那么您可以做的只是在数据库级别添加唯一约束(也称为唯一索引)。这样,在两个字符串相等的远程事件中,数据库将拒绝第二个字符串。
如果你需要将它用于查询,你可能会在该字段上有一个索引,因此它不应该添加任何不合理的开销。
作为旁注,SecureRandom
是 Ruby 库,而不是Rails库。
答案 1 :(得分:1)
为了使它具有唯一性,它必须(i)遵循一条规则,使其永远不会命中先前生成的输出(例如通过在调用它时调用一对一函数,它只能在单个线程下工作,这使得它是非随机的,或者(ii)保留某个地方所有先前生成的输出的记录,但不是这种情况,这也使得它是非随机的。在任何一种情况下,你都应该能够说出它不是唯一的。
然而,数学和工程学是不同的。即使它不是唯一的,您也可以将其视为事实上的独特之处。这就是程序员所做的。
答案 2 :(得分:0)
Rails master分支包含一个与此相关的新模块。 https://github.com/rails/rails/blob/master/activerecord/lib/active_record/secure_token.rb
您可以参考的其他解决方案。