8

Sto tentando di impostare il mio programma in modo che la password venga convalidata solo se viene modificata (in modo che un utente possa modificare altre informazioni senza dover inserire la propria password).Metodo non definito password_changed? Errore

Attualmente sto ottenendo un errore che dice

NoMethodError in UsersController#create, undefined method `password_changed?' for #<User:0x00000100d1d7a0> 

quando provo ad accedere in

Ecco il mio codice di convalida user.rb:.

validates :name, :presence => true, 
:length => { :maximum => 50 } 
validates :email, :presence => true, 
:format  => { :with => email_regex }, 
:uniqueness => { :case_sensitive => false } 
validates :password, :presence =>true, :confirmation => true, :length => { :within => 6..40 }, :if=>:password_changed? 

Ecco il mio metodo create in users_controller.rb:

def create 
    @user = User.new(params[:user]) 
    if @user.save 
     sign_in @user 
     flash[:success] = "Welcome to the Sample App!" 
     redirect_to @user 
    else 
     @title = "Sign up" 
     render 'new' 
    end 
end 

Grazie!

risposta

5

Sostituire con:

:if => lambda {|user| user.password_changed? } 

farei due diverse convalide:

validates :password, :presence =>true, :confirmation => true, :length => { :within => 6..40 }, :on => :create 
validates :password, :confirmation => true, :length => { :within => 6..40 }, :on => :update, :unless => lambda{ |user| user.password.blank? } 
+0

No, si ottiene ancora lo stesso errore. – steffi2392

+1

è 'password' una colonna del tuo modello? – apneadiving

+0

nel database? No, solo password crittografata. Dovrei aggiungerlo? – steffi2392

3

ho incontrato questo stesso problema e dopo aver letto questo post ho implementato il codice suggerito da apneadiving in la sua risposta ma con una leggera modifica:

Ho usato due diverse validazioni, una f o creare:

validates :password, :presence => true, :confirmation => true, :length => { :within => 6..128 }, :on => :create 

e poi ho usato questo per aggiornamento:

validates :password, :presence => true, :confirmation => true, :length => { :within => 6..128 }, :on => :update, :unless => lambda{ |user| user.password.to_s.empty? } 

In origine, ho implementato esattamente quello apneadiving suggerito, ma mi sono reso conto che in aggiornamenti che l'utente non è stato in realtà convalidando la presenza di una stringa. Come in, permetteva a un utente di impostare la propria password su " " (Una stringa di spazio bianco). Ciò è dovuto al fatto che " ".blank? == true, e così se lo avete impostato per convalidare in questo modo:

:unless => lambda { |user| user.password.blank? } 

Allora non verrà eseguito la convalida se una stringa completa di spazi bianchi è presentata dall'utente è presentata perché legge la stringa come vuota. Ciò sostanzialmente invalida l'effetto della convalida della presenza sull'aggiornamento. La ragione per cui ho fatto password.to_s.empty? invece di semplicemente password.empty? è di prevenire errori se qualcuno chiama update_attributes sul modello utente e non passa nulla nella password, campo, quindi la password sarà nil, e poiché la classe rubino nil non avere un vuoto? metodo, genererà un errore. Chiamando .to_s su nil, tuttavia lo convertirà in una stringa vuota, che restituirà true su una successiva chiamata .empty? (quindi la convalida non verrà eseguita). Quindi dopo alcune prove e tribolazioni ho scoperto che questo era il modo migliore per farlo.

1

La modifica da cercare, almeno in Rails 4, è password_digest.

@account.password = "my new password" 
@account.changes # => {"password_digest"=>["$2a$10$nR./uTAmcO0CmUSd5xOP2OMf8n7/vXuMD6EAgvCIsnoJDMpOzYzsa", "$2a$10$pVM18wPMzkyH5zQBvcf6ruJry22Yn8w7BrJ4U78o08eU/GMIqQUBW"]} 
@account.password_digest_changed? # => true 
+0

Questo lo ha risolto per me, grazie! – IGNIS

+0

Allo stesso modo, nessuno dei precedenti ha funzionato per me. Ho finito con questo, nel caso in cui: 'validates_presence_of: password_confirmation, if: lambda {| staff | staff.password.present? } ' Quindi ora richiede password_confirmation sia in fase di creazione che di aggiornamento e solo se è stato inviato anche un attributo password. Sono sorpreso che questo non è un comportamento predefinito. –

1

finiti qui googling questo messaggio di errore, e l'utilizzo di

@account.encrypted_password_changed?

nel mio caso ha dato quello che volevo.