ruby-on-rails - learn - ruby on rails tutorial español
Cómo hacer que las ID de modelos en Rails sean impredecibles y aleatorias (5)
En tu modelo, haz esto:
before_create :randomize_id
...
private
def randomize_id
begin
self.id = SecureRandom.random_number(1_000_000)
end while Model.where(id: self.id).exists?
end
Estoy escribiendo una aplicación de Rails que, por su naturaleza, NO PUEDE requerir que los usuarios se registren y, por lo tanto, no pueden usar la autenticación como el medio habitual para proteger los registros. (Lo sé, lo sé ...) La información del usuario aquí se limita a las direcciones de correo electrónico. Así que necesito una manera de hacer que las identificaciones de mi modelo sean impredecibles para que otras identificaciones no puedan ser adivinadas fácilmente. (Sé que sé...)
He intentado usar complementos como uuidtools para aleatorizar los identificadores a medida que se crean los registros, así:
require ''uuidtools''
class Post < ActiveRecord::Base
def before_create()
self.id = OpenSSL::Digest.SHA1.hexdigest(UUID.timestamp_create())
end
end
... Esto se ve bien al principio, pero suceden cosas divertidas. ActiveRecord a veces intenta insertar un valor de 0 en el id y obtengo errores como "no se puede encontrar Post with id = 0 ''etc ...
Me he quedado sin ideas. ¿Alguien puede ayudar? Gracias.
Hay un plugin que debería hacer lo que quieras:
http://codesnipers.com/?q=using-uuid-guid-as-primary-key-in-rails
(Todas las disculpas a los censores de SO por no pegar todo el artículo. En mi defensa, está cargado de enlaces y formatos que requerirían un poco de esfuerzo para replicar. Sin mencionar que estaríamos robándole el tráfico al autor de la página y los ingresos potenciales.)
La mejor manera es usar SecureRandom.uuid
que genera un UUID V4 (Identificador único universal).
Es prácticamente completamente aleatorio y único (la probabilidad de colisión es algo así como una sobre decenas de trillones): https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29
Esto debería hacer el trabajo :
class Post < ActiveRecord::Base
before_create :generate_random_id
private
def generate_random_id
self.id = SecureRandom.uuid
end
end
O si está utilizando Rails> = 4 y PostgreSQL, puede tenerlos generándolos por usted:
create_table :posts, id: :uuid do |t|
...
end
Lo que está mal aquí es que self.id requiere un int y OpenSSL :: Digest.SHA1.hexdigest (UUID.timestamp_create ()) devuelve una cadena con caracteres no numéricos que llevaría a que el valor ''0'' sea realmente almacenado en la base de datos
Una alternativa es generar un token o una suma de comprobación o lo que sea en una segunda columna durante la creación del registro y, en todos los casos, sus controladores Model.find_by_id_and_token
un objeto, use Model.find_by_id_and_token
.
Entonces siempre generarás URL que contengan y requieran tanto el ID como el token.