Rails "validates_uniqueness_of" Case Sensitivity


93

Ecco il modello (sto usando SQLLite3):

class School < ActiveRecord::Base

  validates_uniqueness_of :name

end

Ad esempio, dopo aver aggiunto "Yale", non posso aggiungere "Yale" ma posso aggiungere "yale". Come posso rendere la convalida senza distinzione tra maiuscole e minuscole?

EDIT: Trovato - Validazioni di record attivi

Risposte:


232

validates_uniqueness_of :name, :case_sensitive => falsefa il trucco, ma si dovrebbe tenere a mente che validates_uniqueness_ofnon non garantire l'unicità, se si dispone di più server / processi server (ad esempio, in esecuzione Phusion passeggeri, più meticci, ecc) o un server multi-threaded. Questo perché potresti ottenere questa sequenza di eventi (l'ordine è importante):

  1. Il processo A riceve una richiesta per creare un nuovo utente con il nome "foo"
  2. Il processo B fa la stessa cosa
  3. Il processo A convalida l'unicità di 'foo' chiedendo al DB se quel nome esiste ancora e il DB dice che il nome non esiste ancora.
  4. Il processo B fa la stessa cosa e ottiene la stessa risposta
  5. Il processo A invia l' insertistruzione per il nuovo record e riesce
  6. Se si dispone di un vincolo del database che richiede l'unicità per quel campo, il processo B invierà l' insertistruzione per il nuovo record e fallirà con un'orribile eccezione del server che ritorna dall'adattatore SQL. Se non si dispone di un vincolo del database, l'inserimento avrà successo e ora si hanno due righe con "foo" come nome.

Vedi anche "Concorrenza e integrità" nella validates_uniqueness_ofdocumentazione di Rails.

Da Ruby on Rails 3a edizione :

... nonostante il suo nome, validates_uniqueness_of non garantisce realmente che i valori delle colonne saranno univoci. Tutto ciò che può fare è verificare che nessuna colonna abbia lo stesso valore di quella del record da convalidare al momento in cui viene eseguita la convalida. È possibile creare due record contemporaneamente, ciascuno con lo stesso valore per una colonna che dovrebbe essere univoca e che entrambi i record superino la convalida. Il modo più affidabile per applicare l'unicità è con un vincolo a livello di database ".

Vedi anche l'esperienza di questo programmatore con validates_uniqueness_of.

Un modo in cui ciò accade comunemente è il doppio invio accidentale da una pagina web durante la creazione di un nuovo account. Questo è difficile da risolvere perché ciò che l'utente riceverà è il secondo (brutto) errore e gli farà pensare che la registrazione non sia riuscita, quando in realtà è riuscita. Il modo migliore che ho trovato per impedirlo è semplicemente usare javascript per cercare di prevenire il doppio invio.


4
Come nota: ecco una patch che ho inviato a Rails per provare a risolvere questo problema utilizzando vincoli a livello di db: rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/…
Jordan Brough

inoltre, c'è il problema perenne "l'utente ha fatto doppio clic sul pulsante di invio", ma è più una soluzione che utilizza: disable_with
Ghoti

77

In rails 3 puoi farlo nel tuo modello:

validates :name, :uniqueness => true

o senza case_sensitivity

validates :name, :uniqueness => {:case_sensitive => false}

Questo è esattamente quello che voglio.
Jigar Bhatt

1
Faccio Rails da oltre 10 anni. Non posso credere che sto solo imparando a conoscere questa opzione. C'è sempre qualcosa di nuovo da imparare in Rails ... indipendentemente dal proprio livello di abilità.
danielricecodes

24

È disponibile un'opzione in cui è possibile specificare l'insensibilità alle maiuscole

  validates_uniqueness_of :name, :case_sensitive => false

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.