Ruby on Rails,Devise gem。 密码为空时如何删除当前密码?

现在我意识到这个话题已经被覆盖过很多次了。 但是,似乎没有一种解决方案只有在数据库中的密码为空时才能使当前密码字段免除。

我目前在我的用户模型中需要密码,如:

def password_required? (authentications.empty? || !password.blank?) && super end 

然后我将更新function复制到我的注册控制器中:

 def update if resource.update_with_password(params[resource_name]) set_flash_message :notice, :updated sign_in resource_name, resource, :bypass => true redirect_to after_update_path_for(resource) else clean_up_passwords(resource) render_with_scope :edit end end 

我只是不知道如何在编辑空密码时确保设备不需要密码,我是否还需要从视图中删除current_password字段并执行此操作?

  

(we need your current password to confirm your changes)

任何建议都会很棒,因为我确信我忽略了一些东西,但我仍然是Rails的新手。 谢谢!

好的,所以我终于弄明白了!

将以下内容添加到您的类RegistrationsController

 def update if resource.update_with_password(params[resource_name]) set_flash_message :notice, :updated sign_in resource_name, resource, :bypass => true redirect_to after_update_path_for(resource) else clean_up_passwords(resource) render_with_scope :edit end end 

然后对您的用户模型进行以下操作:

 def update_with_password(params={}) current_password = params.delete(:current_password) if !params[:current_password].blank? if params[:password].blank? params.delete(:password) params.delete(:password_confirmation) if params[:password_confirmation].blank? end result = if has_no_password? || valid_password?(current_password) update_attributes(params) else self.errors.add(:current_password, current_password.blank? ? :blank : :invalid) self.attributes = params false end clean_up_passwords result end def has_no_password? self.encrypted_password.blank? end 

我唯一感到困惑的是在编辑视图中:

 <% if !current_user.has_no_password? %> 

我把它包裹起来,如果,我原以为它会是:

 <% if current_user.has_no_password? %> 

如果有人能看到任何改进我的代码或更有效的方式让我知道!

需要当前密码字段的另一个非常小的变化:我的目标是永远不需要当前密码,除非他们更新他们的密码。 对于oauth’ed帐户,我在视图中检查facebook id,并且根本不显示密码字段。

在注册控制器中:

 Users::RegistrationsController < Devise::RegistrationsController def update self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key) if resource.update_with_password(params[resource_name]) set_flash_message :notice, :updated if is_navigational_format? sign_in resource_name, resource, :bypass => true respond_with resource, :location => after_update_path_for(resource) else clean_up_passwords(resource) respond_with_navigational(resource){ render_with_scope :edit } end end 

在User.rb中,我使用update_with_password,然后仅当用户在视图的密码字段中输入了内容时才调用verify_password_and_update。 否则,我清除当前的密码参数并调用update_without_password(此方法现在内置于设计中):

 #to remove the current password check if updating a profile originally gotten via oauth (fb, twitter) def update_with_password(params={}) if params[:password].blank? params.delete(:current_password) self.update_without_password(params) else self.verify_password_and_update(params) end end def update_without_password(params={}) params.delete(:password) params.delete(:password_confirmation) result = update_attributes(params) clean_up_passwords result end def verify_password_and_update(params) #devises' update_with_password # https://github.com/plataformatec/devise/blob/master/lib/devise/models/database_authenticatable.rb current_password = params.delete(:current_password) if params[:password].blank? params.delete(:password) params.delete(:password_confirmation) if params[:password_confirmation].blank? end result = if valid_password?(current_password) update_attributes(params) else self.attributes = params self.valid? self.errors.add(:current_password, current_password.blank? ? :blank : :invalid) false end clean_up_passwords result end