Ruby-on-rails 设计无密码更新用户
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5113248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Devise update user without password
提问by kriysna
I want to update users attributes without password in devise. The case is like, if password and password confirmation fields are not blank then I need devise error and if they are blank then other user attributes need to be updated. How could I do this with devise?
我想在没有密码的情况下更新用户属性。情况就像,如果密码和密码确认字段不为空,那么我需要设计错误,如果它们为空,则需要更新其他用户属性。我怎么能用设计做到这一点?
Thanks in advance!
提前致谢!
采纳答案by Dty
Is this what you're look for? From the Devise wiki
这是你要找的吗?来自设计维基
Allow users to edit their account without providing a password
It shows how to do it for rails 3 and rails 4
它显示了如何为 rails 3 和 rails 4 执行此操作
=======================
========================
John's solutionis a simpler alternative
约翰的解决方案是一个更简单的选择
回答by John
I think this is a much better solution:
我认为这是一个更好的解决方案:
if params[:user][:password].blank? && params[:user][:password_confirmation].blank?
params[:user].delete(:password)
params[:user].delete(:password_confirmation)
end
This prevents you from having to change the Devise controller by simply removing the password field from the form response if it is blank.
这可以防止您通过简单地从表单响应中删除密码字段(如果它是空白的)来更改设计控制器。
Just be sure to use this before@user.attributes = params[:user]or whatever you use in your updateaction to set the new parameters from the form.
请务必在之前@user.attributes = params[:user]或在update操作中使用的任何内容之前使用它来设置表单中的新参数。
回答by Duncan Robertson
I think with Devise 3.2+ you can just override update_resource in your subclassed controller. Here's an example for the question originally asked:
我认为使用 Devise 3.2+ 你可以在你的子类控制器中覆盖 update_resource 。这是最初提出的问题的示例:
class MyRegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
end
回答by Mikhail Grishko
I solved this problem as follows: if form submitting with password, then need fill current_password field or form updated without password and current_password
我解决这个问题如下:如果表单提交密码,则需要填写 current_password 字段或没有密码和 current_password 更新表单
in model:
在模型中:
class User
devise: bla-bla-bla
attr_accessor :current_password
end
In controller:
在控制器中:
class Users::RegistrationsController < Devise::RegistrationsController
layout 'application'
def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
# custom logic
if params[:user][:password].present?
result = resource.update_with_password(params[resource_name])
else
result = resource.update_without_password(params[resource_name])
end
# standart devise behaviour
if result
if is_navigational_format?
if resource.respond_to?(:pending_reconfirmation?) && resource.pending_reconfirmation?
flash_key = :update_needs_confirmation
end
set_flash_message :notice, flash_key || :updated
end
sign_in resource_name, resource, :bypass => true
respond_with resource, :location => after_update_path_for(resource)
else
clean_up_passwords resource
respond_with resource
end
end
end
回答by graudeejs
I instead override #password_required? method inside user model.
我改为覆盖#password_required?用户模型中的方法。
class User < ActiveRecord::Base
devise :database_authenticatable, :validatable #, ...
def password_required?
if respond_to?(:reset_password_token)
return true if reset_password_token.present?
end
return true if new_record?
password.present? || password_confirmation.present?
end
end
So if user is new he will be required to specify password. However exist user will be required to specify password only if he fills in either password or password_confirmation attributes.
因此,如果用户是新用户,他将需要指定密码。但是,仅当用户填写 password 或 password_confirmation 属性时,才要求存在用户指定密码。
For more details see: https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L33
有关更多详细信息,请参阅:https: //github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L33
My implementation is almost identical as original: https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L53
我的实现与原始实现几乎相同:https: //github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L53
except that I check for presence (which returns false for blank strings)
除了我检查是否存在(对于空白字符串返回 false)
Here's discussion about my pull request on this matter: https://github.com/plataformatec/devise/pull/3920
这是关于我对此事的拉取请求的讨论:https: //github.com/plataformatec/devise/pull/3920
回答by rb-
I solve this problem with my interface. There are two ways it can go.
我用我的界面解决了这个问题。它有两种方式。
Disable the fields if they are empty
如果字段为空,则禁用它们
This bit of jQuery disables the fields before the form submits in the event that they are empty. It requires a certain markup pattern, check the demo on Codepen.
如果字段为空,jQuery 的这一位会在表单提交之前禁用这些字段。它需要一定的标记模式,请查看Codepen 上的演示。
$(".password-fields").each(function() {
var $fields, $form;
$form = $(this).parents("form");
$fields = $(this).find("input");
$form.on("submit", function() {
$fields.each(function() {
if ($(this).val() === "") {
$(this).attr("disabled", "disabled");
}
});
});
});
Give the user a checkbox to select if they want to update
给用户一个复选框以选择他们是否要更新
Another option is to remove the password fields from the form if the user hasn't indicated that they want to update their password. Here's the example on CodePen.
如果用户没有表明他们想要更新他们的密码,另一种选择是从表单中删除密码字段。这是CodePen上的示例。
$(".password-fields").each(function () {
var $fields, $button, html;
$fields = $(this);
$button = $fields.prev(".update-password").find("input");
html = $fields.html();
$button
.on("change", function () {
if ( $(this).is(":checked") ) {
$fields.html(html);
}
else {
$fields.html("");
}
})
.prop("checked", "checked")
.click();
});
In either case, it requires no update to the app itself. You are just submitting the fields you want to change.
在任何一种情况下,它都不需要更新应用程序本身。您只是提交要更改的字段。
回答by Sebyddd
If you still want to support password change but make it optional, check the availability of current_passwordas such:
如果您仍然希望支持密码更改但使其成为可选,请检查以下内容的可用性current_password:
class MyRegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
if params[:current_password].blank?
resource.update_without_password(params.except(:current_password))
else
resource.update_with_password(params)
end
end
end
That way if the current_password is present you can proceed and update the password, else ignore it and update without password.
这样,如果 current_password 存在,您可以继续并更新密码,否则忽略它并在没有密码的情况下更新。
回答by Changwoo Rhee
params[:user][:password] is not working in rails 6
params[:user][:password] 在 rails 6 中不起作用
You have to change params[:user][:password]to params[:password]
您必须将params[:user][:password]更改为params[:password]
Remove [:user] in all params
删除所有参数中的 [:user]
my source code is below
我的源代码在下面
before run this command
在运行此命令之前
rails generate devise:controllers users -c=registrations
rails generate devise:controllers users -c=registrations
class Users::RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
protected
def update_resource(resource, params)
puts "params ===> #{params}"
if params[:password].blank? && params[:password_confirmation].blank?
params.delete(:password)
params.delete(:password_confirmation)
params.delete(:current_password)
resource.update_without_password(params)
else
super
end
end
end
回答by Roman
As workaround put in your User model
作为您的用户模型中的解决方法
def password_required?
encrypted_password.blank? || encrypted_password_changed?
end
回答by Maxim Kachanov
If you want Devise to check current password only when user tries to change password(that means you canchange other attributes without providing current password):
如果您希望设计仅在用户尝试更改密码时检查当前密码(这意味着您可以在不提供当前密码的情况下更改其他属性):
class RegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
if params[:password].blank? && params[:password_confirmation].blank?
resource.update_without_password(params)
else
super
end
end
end
Also in your model:
同样在您的模型中:
attr_accessor :current_password
And don't forget about
不要忘记
devise_for :users, controllers: {registrations: 'registrations'}
in routes.rb.
在routes.rb 中。

