2013-07-30 23 views
6

con binari 4 utilizzo has_secure_password nel mio modello utente, il trucco dice che se non settaggio: password_confirmation non verrà mai attivato ma perché quando eseguo il test ottengo errore : conferma password non può essere vuoto come il seguente:rails 4 has_secure_password rendering password conferma opzionale

Failures: 

1) User 
Failure/Error: it { should be_valid } 
    expected #<User id: nil, name: "joe", email: "[email protected]", created_at: nil, 
    updated_at: nil, password_digest: "$2a$04$mcRr/msgYQR3kBVc3kv/m.UotBJuJuSXZKMw 
    /eHTvU87..."> to be valid, but got errors: Password confirmation can't be blank 

la mia prova di file simile a:

require 'spec_helper' 

describe User do 

    before { @user = User.new(name: 'joe', email: '[email protected]', password: 'foo') } 

    subject { @user } 
    #.... 
    #.... 
    describe "when password is not present" do 
    before { @user.password = "" } 
    it { should_not be_valid } 
    end 
end 

perché ottengo questo errore, non v'è oluzione per quello? before linea di

risposta

5

Modifica il test di ringraziamento a questo:

before { @user = User.new(
    name: 'joe', 
    email: '[email protected]', 
    password: 'foo', 
    password_confirmation: 'foo') #<== this line! 
} 

Questo dovrebbe risolvere il problema.

questo che si tratta:

Sai come quando si crea un nuovo account su praticamente qualsiasi sito web, ti chiedono di fare una password e inserire due volte? Questo è quello che è. Quando crei un nuovo utente, has_secure_password vuole la password due volte per assicurarti di non aver commesso errori di battitura.

Se password! = password_confirmation, genera un'eccezione e l'utente non verrà creato.

Anche in questo caso, viene utilizzato solo per la creazione . Non è necessario inserire due password nel modulo di login o altro. Non è necessario aggiungere questo campo al modello o al DB.

Se si dispone di un modulo di creazione utente e non si desidera avere un campo password_confirmation, non è necessario. È possibile impostare password_confirmation = password nel controller, prima di chiamare il salvataggio o qualsiasi altra cosa.

Ma per l'utente creazione, il mosto password_confirmation essere presente.

+0

ma non vorrei aggiungere password_confirmation alla mia app, ho bisogno solo di una password una volta – medBo

+0

Viene utilizzato solo durante la creazione dell'utente. Non devi (e non devi) aggiungerlo al tuo modello. Questa è una caratteristica di 'has_secure_password'. –

+0

non capisco per favore, puoi spiegare di più! (nella mia forma vorrei giustificare un campo per la password e non un altro per la conferma della password) – medBo

21

farla breve

has_secure_password validations: false # This is the key to the solution 
validates :password, presence: true, length: { minimum: 6 } # Or an length you want 

La Lunga storia

  1. Il docs e the source code dicono:

    Se non hanno bisogno della convalida conferma , non impostare alcun valore all'attributo password_confirmation e la convalida non verrà attivata.

  2. Ma anche dire:

    convalide per presenza di password su creare, la conferma della password di (con un + password_confirmation + attributo) sono aggiunti automaticamente. Se si desidera disattivare le convalide, passare convalide: false come argomento . È possibile aggiungere ulteriori convalide a mano se necessario.

  3. L'articolo n. 1 non è una descrizione completa. Dobbiamo disattivare tutte le convalide e aggiungere le nostre regole di convalida per farlo funzionare come descritto al punto # 2.

ho trascorso qualche tempo su questo e ha ottenuto una lezione: trovare il codice sorgente quando si sono confusi. Questo sembra essere un modo doloroso o difficile, ma a volte è la strada giusta.

+0

presenza: true non funziona come convalida: false rimuove la condizione di presenza. Tuttavia, poiché la lunghezza minima è 6, non importa – shailesh

+1

Rails 4 ignora completamente la conferma se non la invii come parametro, quindi se dimentichi di autorizzare l'attributo 'password_confirmation', verrà ignorato e le tue convalide vinte dire una cosa Attento a questo! –

+0

@shailesh 'validations: false' rimuove solo le convalide predefinite aggiunte da' has_secure_password'. L'aggiunta di convalide personalizzate come 'presence: true' nel campo della password funzionerà comunque come previsto. – mltsy

1

ho fatto questo come misura temporanea fino a ottenere questa applicazione da Rails 4.0.13 a 4.1 e oltre:

class User < ActiveRecord::Base 
    has_secure_password 
    # Tempfix until Rails 4.1 https://github.com/rails/rails/pull/11107#issuecomment-21850919 
    raise "Get rid of this on Rails 4.1+" if Rails::VERSION::STRING != "4.0.13" 
    before_validation { self.password_confirmation ||= password } 
end 
+0

Che cosa fa esattamente questo, rimuove la convalida o rende la conferma della password uguale alla password? –

+1

@ SurgePedroza Quest'ultimo. Se la conferma è nulla, viene assegnato il valore della password prima dell'esecuzione delle convalide. –

Problemi correlati