Ruby on rails 轨道&x2B;设计:使用或不使用pasword更新用户
有很多相关的问题:Ruby on rails 轨道&x2B;设计:使用或不使用pasword更新用户,ruby-on-rails,ruby,devise,Ruby On Rails,Ruby,Devise,有很多相关的问题: - - - -等等 但是,当我试图用他们的答案工作时,我从来没有得到我想要的,所以我决定发布这种问答风格 情况: 我当时正在使用一个应用程序,我想要一个“管理配置文件表单”。我想要一个表单来更新用户信息,包括电子邮件和密码,还有名字、姓氏和其他非设计字段。我只想在用户试图更改密码时需要密码字段(password和password\u confirmation)。我还想用助手构建我的表单,并将用户能够更新的字段列为白名单。我还想要Desive提供的所有方便的错误信息(比如,“您
-
-
-
-等等 但是,当我试图用他们的答案工作时,我从来没有得到我想要的,所以我决定发布这种问答风格 情况:
我当时正在使用一个应用程序,我想要一个“管理配置文件表单”。我想要一个表单来更新用户信息,包括电子邮件和密码,还有名字、姓氏和其他非设计字段。我只想在用户试图更改密码时需要密码字段(password和password\u confirmation)。我还想用助手构建我的表单,并将用户能够更新的字段列为白名单。我还想要Desive提供的所有方便的错误信息(比如,“您的密码必须至少包含8个字符。”或者其他任何信息);DR:剥离
参数
仅为满足您的需要,我称之为用户参数
。在处理表单的操作中,检查user\u params[:password]
是否为空,以及是否尝试使用@user.update不使用密码(user\u params)
更新@user.update(user\u params)
模型。如果适用的更新调用返回false
@user.errors
保留解释
我是如何解决这个问题的:我在我的
config/routes
文件中定义了资源
:
resource :profile
我为我的资源制作了一个控制器,它扩展了Desive的authenticated controllerProfilesController
,用于管理配置文件。配置文件控制器包含几个方法
包括user_params
,主要过滤params
到白名单:
def user_params
accessible = [
:first_name,
:last_name,
:email,
:password,
:password_confirmation
]
params.require(:user).permit(accessible)
end
和update
处理表单的业务:
def update
# current_user holds the logged in user
@user = current_user
# IF they've left the password field blank,
# AND the devise update_without_password method returns true
# OR IF a full update of user (including password and password_confirmation) returns true
# THEN re-sign them in to flush their session, and redirect them back to their dashboard, and send a success message.
# ELSE re-present the edit form they were just on (there's a handy catcher
# in the edit view script to render the form errors, you can find them on
# @user.errors)
if (user_params[:password].blank? && @user.update_without_password(user_params)) || @user.update(user_params)
sign_in(@user, bypass: true)
redirect_to '/dashboard', notice: 'Your profile changes have been saved.'
else
render 'edit'
end
end
= form_for current_user, as: :user, url: profile_path, html: { class: '' } do |f|
# [f.label, f.text_field, f.password_field, etc...]
当然还有一个视图脚本(在我的例子中是haml脚本-app/views/profiles/edit.html.haml
),它使用form\u for
来呈现表单:
def update
# current_user holds the logged in user
@user = current_user
# IF they've left the password field blank,
# AND the devise update_without_password method returns true
# OR IF a full update of user (including password and password_confirmation) returns true
# THEN re-sign them in to flush their session, and redirect them back to their dashboard, and send a success message.
# ELSE re-present the edit form they were just on (there's a handy catcher
# in the edit view script to render the form errors, you can find them on
# @user.errors)
if (user_params[:password].blank? && @user.update_without_password(user_params)) || @user.update(user_params)
sign_in(@user, bypass: true)
redirect_to '/dashboard', notice: 'Your profile changes have been saved.'
else
render 'edit'
end
end
= form_for current_user, as: :user, url: profile_path, html: { class: '' } do |f|
# [f.label, f.text_field, f.password_field, etc...]
我的用户模型还包括所有Desive-y优点:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :receipts
validate :first_name, presence: true
validate :last_name, presence: true
validate :email, presence: true, email: true
end
class用户
如果您确实想在不使用当前\u密码的情况下更新密码,则需要使用用户重置\u密码
方法
@user.reset_password(params[:user][:password], params[:user][:password_confirmation])
以下是在所有情况下都适用的问题的完整工作解决方案:
if params.dig(:user, :password).blank?
updated = @user.update_without_password(params[:user].to_unsafe_hash)
else
if params.dig(:user, :current_password).nil?
@user.reset_password(params[:user][:password], params[:user][:password_confirmation])
updated = @user.update_without_password(params[:user].to_unsafe_hash)
else
updated = @user.update_with_password(params[:user].to_unsafe_hash)
end
bypass_sign_in(@user)
end
记录在案:这是“官方”解决方案-。