8

Próbuję ustawić mój program tak, aby hasło było sprawdzane tylko wtedy, gdy zostało zmienione (aby użytkownik mógł edytować inne informacje bez konieczności wprowadzania hasła).Niezdefiniowana metoda password_changed? Błąd

Jestem obecnie otrzymuję błąd, który mówi

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

gdy próbuję się zalogować

Oto mój kod walidacji w 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? 

Oto moja tworzyć metoda w 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 

Dziękujemy!

Odpowiedz

5

Replace with:

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

zrobiłbym dwa różne walidacje:

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

Nie, nadal otrzymuję ten sam błąd. – steffi2392

+1

to "hasło" to kolumna Twojego modelu? – apneadiving

+0

w bazie danych? Nie, tylko zaszyfrowane_hasło. Czy powinienem go dodać? – steffi2392

3

I napotkał ten sam problem i po przeczytaniu tego postu I wdrożone kod sugerowanego przez apneadiving w jego odpowiedź, ale z niewielką modyfikacją:

Użyłem dwóch różnych walidacji, jeden f lub utworzyć:

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

a następnie użyłem to jedno za UPDATE:

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

Początkowo I wdrożone dokładnie to, co sugeruje apneadiving, ale zdałem sobie sprawę, że o aktualizacjach użytkownik nie został faktycznie walidacji obecność ciągu. Tak jak w przypadku, zezwolono użytkownikowi na ustawienie hasła na " " (ciąg białych znaków). Wynika to z faktu, że " ".blank? == true, a więc jeśli masz to ustawione, aby potwierdzić tak:

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

Wtedy nie będzie uruchomić sprawdzanie czy ciąg pełen białych znaków jest składany przez użytkownika jest wniosek, ponieważ odczytuje ciąg jako puste. Zasadniczo powoduje to unieważnienie efektu sprawdzania poprawności obecności w aktualizacji. Powodem, dla którego zrobiłem password.to_s.empty? zamiast po prostu password.empty? jest zapobieganie błędom, jeśli ktoś wywołuje update_attributes w modelu użytkownika i nie przekazuje niczego do hasła, pola, wtedy hasło będzie nil, a ponieważ klasa ruby ​​nil nie mieć puste? metoda, spowoduje błąd. Wywołanie .to_s na nil, jednak przekonwertuje go na pusty ciąg, który zwróci wartość true podczas kolejnego wywołania .empty? (w ten sposób sprawdzanie poprawności nie zostanie uruchomione). Po kilku próbach i ucisku odkryłem, że jest to najlepszy sposób na zrobienie tego.

1

Zmiana, o której należy pamiętać, przynajmniej w przypadku Rails 4, to 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

Naprawiłem to dla mnie, dziękuję! – IGNIS

+0

Podobnie, żaden z powyższych nie działał dla mnie. Skończyło się na tym, na wszelki wypadek: 'validates_presence_of: password_confirmation, if: lambda {| staff | staff.password.present? } ' Teraz wymaga on password_confirmation zarówno przy tworzeniu, jak i aktualizacji, i tylko wtedy, gdy wysłano również atrybut hasła. Jestem zaskoczony, że to nie jest domyślne zachowanie. –

1

Skończyło się tutaj googlowania ten komunikat o błędzie, a przy użyciu

@account.encrypted_password_changed?

w moim przypadku dało to, co chciałem.

Powiązane problemy