Aqui está o que estou usando. O token não precisa necessariamente ser ouvido para adivinhar; é mais como um identificador de URL curto do que qualquer outra coisa, e eu quero mantê-lo curto. Segui alguns exemplos que encontrei on-line e, no caso de uma colisão, acho que o código abaixo recriará o token, mas não tenho certeza. Estou curioso para ver melhores sugestões, no entanto, pois isso parece um pouco áspero nas bordas.
def self.create_token
random_number = SecureRandom.hex(3)
"1X#{random_number}"
while Tracker.find_by_token("1X#{random_number}") != nil
random_number = SecureRandom.hex(3)
"1X#{random_number}"
end
"1X#{random_number}"
end
Minha coluna do banco de dados para o token é um índice exclusivo e também estou usando validates_uniqueness_of :token
no modelo, mas como eles são criados em lotes automaticamente com base nas ações de um usuário no aplicativo (eles fazem um pedido e compram os tokens, essencialmente), é não é possível que o aplicativo gere um erro.
Acho que eu também poderia reduzir a chance de colisões, acrescentar outra sequência no final, algo gerado com base no tempo ou algo assim, mas não quero que o token fique muito tempo.