2010-08-22 2 views
19

Il modello utente contiene: nome,: indirizzo email e: campi password. Tutti e 3 hanno convalide per la lunghezza. Una pagina Web di "aggiornamento account" consente all'utente di aggiornare il proprio nome e indirizzo email, ma la password non è. Quando presentate, params [: utente] èIn Rails 3, come posso saltare la convalida del campo password quando non sto tentando di aggiornare la password?

{"name"=>"Joe User", "email"=>"[email protected]"} 

Nota non c'è una chiave "password", perché il modulo non contiene un tale campo di input.

Quando chiamo

@user.update_attributes(params[:user]) 

la convalida della password non riesce. Tuttavia, poiché non sto tentando di aggiornare la password, non voglio che la convalida della password venga eseguita su questo aggiornamento. Sono confuso perché la convalida della password è in esecuzione quando params [: utente] non contiene una chiave "password".

Nota che voglio avere una pagina web separata altrove che permetta all'utente di aggiornare la sua password. E per tale invio, la convalida della password deve essere eseguita.

Grazie.

+1

Non deve essere in esecuzione la convalida della password e in mancanza se il campo della password è valido per primo. Dici che non stai passando la password, ma ho i miei sospetti. –

risposta

27

La mia applicazione fa qualcosa di simile

attr_accessor :updating_password 

validates_confirmation_of :password, :if => should_validate_password? 

def should_validate_password? 
    updating_password || new_record? 
end 

quindi bisogna model.updating_password = true per la verifica di prendere posto, e non si hanno a che fare questo su creazione.

Che ho trovato su un buon Railscast a http://railscasts.com/episodes/41-conditional-validations

+0

Grazie, mathepic. Questo ha funzionato per me. – Sanjay

+0

Forse usare l'helper 'password_changed?'? –

+0

@PeterEhrlich che genererà un metodo mancante quando si utilizza 'has_secure_password'. Dovresti chiamarlo su 'password_digest' dato che, se la password è presente, verrà rehashed. – Mohamad

0

Un app che sto lavorando utilizza la seguente:

validates_confirmation_of :password, 
           :if => Proc.new { |account| 
               !account.password.blank? 
               || !account.password_confirmation.blank? 
               || account.new_record? } 

A seconda delle esigenze, si potrebbe desiderare di rimuovere il new_record? check

+0

Sembra che stia rimuovendo il punto di conferma - Non confermerai se non hanno specificato la conferma nel modulo. – alternative

+0

Hmm ... sembra un insetto, hai ragione. –

1

Nel modello utente, è possibile ignorare la convalida della password se non è impostata.

validates_length_of :password, :minimum => N, :unless => lambda {|u| u.password.nil? } 
+3

Questo permetterebbe a qualcuno di impostare una password vuota? – Pete

1

Utilizzando update_attributes non cambierà il valore della password, se non c'è una chiave per esso nel hash params.

La convalida non viene eseguita solo nei campi modificati. Valida anche i valori esistenti.

La convalida deve essere in errore perché il campo della password contiene alcuni contenuti non validi che sono già stati salvati nel database. Immagino che sia probabilmente perché lo stai tagliando dopo la convalida e stai provando a convalidare la stringa con hash.

È possibile utilizzare un attributo virtuale (una variabile di istanza o un metodo) che si convalida con un metodo personalizzato e quindi assegnare l'hash al campo della password memorizzata. Date un'occhiata a this technique per le idee.

0
When password is added then only confirmation will be called and presence will call on create action only 

    **validates_presence_of :password, :on =>:create** 

    **validates_confirmation_of :password**