问题
I am trying to create a form to allow users to change their password:
View:
- form_tag change_password_users_path do
= error_messages_for :user, :header_message => "Please Try Again", :message => "We had some problems updating your account"
%br
= label_tag :password, "New password:"
= password_field_tag "password"
%br
= label_tag :password_confirmation, "NConfirm new password:"
= password_field_tag "password_confirmation"
%br
= submit_tag "Update Account"
Controller:
def change_password
@user = current_user
if request.post?
@user.password = params[:password]
@user.password_confirmation = params[:password_confirmation]
if @user.save
redirect_to user_path(current_user)
else
render :action => "change_password"
end
end
end
Authlogic is catching validation errors when the password is 'too short' or the password doesn't match the confirmation, but doesn't do anything when the form is submitted with both fields blank. @user.save must be returning true, because I am redirected to 'user_path(current_user)'.
The password is not actually changed in the database.
Thanks for your help.
回答1:
I suggest you call @user.changed? like the following example to check for blank passwords:
def change_password
@user = current_user
if request.post?
@user.password = params[:user][:password]
@user.password_confirmation = params[:user][:password_confirmation]
if @user.changed? && @user.save
redirect_to user_path(current_user)
else
render :action => "change_password"
end
end
end
回答2:
I think you should also provide the params[:user][:current_password], otherwise you can not save the @user. And when I tested, I found the current_user will be lost after changing password, so you need update usersession.
Add a 'current_password' accessor to your user model
class User < ActiveRecord::Base
act_as_authentic
attr_accessor :current_password
end
In the user controller
def change_password
@user = current_user
if @user.valid_password? params[:user][:current_password]
@user.password = params[:user][:password]
@user.password_confirmation = params[:user][:password_confirmation]
if @user.changed? && @user.save
UserSession.create(:login => @user.login, :password => params[:user][:password])
redirect_to user_path(current_user)
else
render :action => "change_password"
end
end
end
回答3:
Apparently this is the intended behavior.
http://www.ruby-forum.com/topic/198836
At least I know now...
Thanks.
回答4:
Another way to do it is to exploit ActiveModel validation contexts. You will need to add a context-dependent validation to your User model:
validates :password, # :password_confirmation,
:presence => {:message => 'Please enter your new password.'},
:on => :reset_password
Then, in the controller it will be just:
def change_password
@user = current_user
if request.post?
@user.password = params[:password]
@user.password_confirmation = params[:password_confirmation]
if @user.save(:context => :reset_password)
redirect_to user_path(current_user)
else
render :action => "change_password"
end
end
end
Hope it will suite ones who were not satisfied with other suggested solutions.
来源:https://stackoverflow.com/questions/1753822/changing-password-with-authlogic-validation-not-catching-blank-inputs