ruby-on-rails - validations - rails validates if
Rails "validates_uniqueness_of" Sensibilidad de mayúsculas y minúsculas (4)
Aquí está el modelo (estoy usando SQLLite3):
class School < ActiveRecord::Base
validates_uniqueness_of :name
end
Por ejemplo, después de agregar "Yale", no puedo agregar "Yale" pero puedo agregar "yale". ¿Cómo puedo hacer que la validación sea insensible?
EDITAR: Lo encontré - Validaciones de registros activos
En rails 3 puedes hacer esto en tu modelo:
validates :name, :uniqueness => true
o sin case_sensitivity
validates :name, :uniqueness => {:case_sensitive => false}
Hay una opción donde puede especificar la insensibilidad de mayúsculas y minúsculas
validates_uniqueness_of :name, :case_sensitive => false
Hay una pregunta similar, pero la respuesta es más interesante: https://.com/a/6422771
Básicamente, usar :case_sensitive => false
realiza una consulta de base de datos muy ineficiente.
validates_uniqueness_of :name, :case_sensitive => false
hace el truco, pero debes tener en cuenta que validates_uniqueness_of
no garantiza la exclusividad si tienes múltiples servidores / procesos de servidor (por ejemplo, corriendo Phusion Passenger, múltiples Mongrels, etc.) o un servidor multiproceso . Eso se debe a que puede obtener esta secuencia de eventos (el orden es importante):
- El proceso A recibe una solicitud para crear un nuevo usuario con el nombre ''foo''
- El proceso B hace lo mismo
- El proceso A valida la singularidad de ''foo'' preguntando al DB si ese nombre existe todavía y el DB dice que el nombre aún no existe.
- El proceso B hace lo mismo y obtiene la misma respuesta
- El proceso A envía la declaración de
insert
para el nuevo registro y tiene éxito - Si tiene una restricción de base de datos que requiere unicidad para ese campo, el Proceso B enviará la instrucción de
insert
para el nuevo registro y fallará con una fea excepción de servidor que proviene del adaptador de SQL. Si no tiene una restricción de base de datos, la inserción tendrá éxito y ahora tiene dos filas con ''foo'' como nombre.
Consulte también "Concurrencia e integridad" en validates_uniqueness_of
Rails documentation.
De Ruby on Rails 3rd Edition :
... a pesar de su nombre, validates_uniqueness_of realmente no garantiza que los valores de las columnas sean únicos. Todo lo que puede hacer es verificar que ninguna columna tenga el mismo valor que en el registro que se valida en el momento en que se realiza la validación. Es posible que se creen dos registros al mismo tiempo, cada uno con el mismo valor para una columna que debe ser única, y para que ambos registros pasen la validación. La forma más confiable de hacer cumplir la singularidad es con una restricción de nivel de base de datos ".
Ver también la experiencia de este programador con validates_uniqueness_of
.
Una forma en que esto sucede comúnmente es una doble presentación accidental de una página web cuando se crea una nueva cuenta. Esto es difícil de resolver porque lo que el usuario recibirá es el segundo error (feo) y les hará pensar que su registro falló, cuando en realidad tuvo éxito. La mejor manera que he encontrado para evitar esto es simplemente usar JavaScript para tratar de evitar el doble envío.