Ruby on rails Ruby on Rails,设计宝石。密码为空时如何删除当前密码?

Ruby on rails Ruby on Rails,设计宝石。密码为空时如何删除当前密码?,ruby-on-rails,ruby-on-rails-3,passwords,devise,Ruby On Rails,Ruby On Rails 3,Passwords,Devise,现在我意识到这个话题已经被讨论过很多次了。但是,似乎没有一个解决方案希望仅当数据库中的密码为空时才免除当前密码字段 我目前拥有我的用户模型中所需的密码,如: def password_required? (authentications.empty? || !password.blank?) && super end 然后,我将更新功能复制到我的注册控制器中: def update if resource.update_with_password(params[reso

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

我目前拥有我的用户模型中所需的密码,如:

def password_required?
  (authentications.empty? || !password.blank?) && super
end
然后,我将更新功能复制到我的注册控制器中:

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
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
我只是不知道如何确保Desive在编辑空白密码时不需要密码,我是否还需要从视图中删除当前_密码字段并执行此操作

<% if current_user.password_required? %>
  <p><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
  <%= f.password_field :current_password %></p>
<% end %>
<p><%= f.submit "Update" %></p>

(我们需要您当前的密码来确认您的更改)


任何关于这方面的建议都会很好,因为我确信我忽略了一些东西,但总体上我对Rails还是新手。谢谢

好吧,我终于明白了

将以下内容添加到类注册控制器
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,并且根本不显示密码字段

在注册控制器中:

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
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

当前用户。没有密码吗?
如果没有密码,则返回
true
,因此if语句执行其块。你在用否定的语言来验证那句话。。。除非当前用户没有密码,否则您应该编写
,但它读起来仍然很有趣。如果您使用
当前用户。是否拥有密码?
并将定义设置为返回
self.encrypted\u password.present?
(我知道这已经在下面讨论过了,但这属于注释,我已经给出了一个替代的、更可读的解决方案)我将其用作其他内容的基础,并且它非常有效。唯一的改变:我必须删除
if!params[:current_password].blank?
以避免出现大量分配错误,因为当前密码被设置为
(因此
blank?==true
),所以没有从params中删除,然后
更新属性(params)
尝试使用
:current_password=>更新用户记录
-显然失败,因为
当前\u密码
不是用户的属性。。。也许我搞错了?
self
s不是多余的吗?我尝试了这个解决方案,我得到了无法批量分配受保护的属性:current_password@wulftone我认为根据这一原理,您最终会为所有布尔返回方法每次创建两个版本的方法。人们会恨你吗。有些人讨厌消极的东西。你使用的方法主要是当它是一个布尔结果时,然后无论如何命名它,使它在大多数情况下都是正确的。但是如果您同时使用这两个结果,那么我认为定义一个新方法是最麻烦的。非常感谢您分享您的代码。我有一段时间一直在做这件事,看到你的代码帮助了我=)