使用Devise和Omniauth编辑用户

我正在通过Railscast实施Devise和OmniAuth(以及Devise 文档 ) – 目前,我有一个网站,访问者可以使用他们的Facebook帐户或填写表格进行注册。

但是,当通过OmniAuth注册的用户尝试编辑他们的个人资料时,我遇到了麻烦。 当用户提交对其个人资料的更改时,Devise会查找用户的当前密码,但是那些使用facebook登录的用户不知道他们的密码(他们是在用户模型中自动设置的):

def self.find_for_facebook_oauth(auth, signed_in_resource=nil) user = User.where(:provider => auth.provider, :uid => auth.uid).first unless user user = User.create(first_name:auth.extra.raw_info.first_name, last_name:auth.extra.raw_info.last_name, provider:auth.provider, uid:auth.uid, email:auth.info.email, password:Devise.friendly_token[0,20] ) end user end 

当用户编辑他的信息时,如果他通过OmniAuth设置了他的帐户,则该应用程序不应要求密码确认。 教程建议方便的password_required? 方法将帮助我实现这一结果。 具体来说,将此方法添加到用户模型意味着它应该仅在用户未通过OmniAuth注册时返回true(在这种情况下提供者属性将为nil):

 def password_required? super && provider.blank? end 

因此,一段代码如:

  resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>   "essential_user_info_inputs", :locals => { :f => f } %>  "inessential_user_info_inputs", :locals => { :f => f } %>   "password_inputs", :locals => { :f => f } %>  (we need your current password to confirm your changes)

理论上只在需要时显示密码输入。 它还表明Devise内置了逻辑,称OmniAuth用户不需要使用密码来编辑他们的帐户。 我不知道这是否属实,但是这种教程使它看起来像那样。 但是当OmniAuth用户尝试编辑他的帐户时,我会收到“当前密码不能为空”。 非OmniAuth用户也是如此(这是有道理的,因为密码字段也不会显示在这些用户的编辑页面上)。

有些戳了一下确认了password_required? 当用户通过OmniAuth注册并通过网站的常规用户注册时,方法返回false。 即使我将其更改为只运行超类方法,它也会返回false。

有关password_required方法发生了什么的任何想法? 我在任何地方都找不到任何关于它的东西,但我觉得这就是现在绊倒的东西。

更新:

这现在有效,但是没有使用Railscast中概述的方法,它依赖于requires_password? 方法,一个我仍然一无所知的话题。 相反,我实现了此处概述的解决方案,如此处所示 。 所以我现在只要求密码用代码更新非OmniAuth帐户:

 class Users::RegistrationsController  true redirect_to root_path else render "edit" end end end 

最简单的方法是覆盖RegistrationsController的update_resource方法。 这是建议他们自己实现的控制器:

  # By default we want to require a password checks on update. # You can overwrite this method in your own RegistrationsController. def update_resource(resource, params) resource.update_with_password(params) end 

所以解决方案是在你自己的控制器中覆盖这个方法,如下所示:

 class Users::RegistrationsController < Devise::RegistrationsController # Overwrite update_resource to let users to update their user without giving their password def update_resource(resource, params) if current_user.provider == "facebook" params.delete("current_password") resource.update_without_password(params) else resource.update_with_password(params) end end end 

我在下面的链接中添加了一个更新,其中包括我对Devise / OmniAuth更改用户配置文件/密码问题的解决方案,并收集了一些有用的链接:

stackoverflow – 允许用户编辑帐户而无需在设计中保存密码

我看到这个用在某个地方。

 def update params[:user].delete(:current_password) params[:user].delete(:password) params[:user].delete(:password_confirmation) if current_user.update_without_password(params[:user]) redirect_to somewhere_wicked_path, notice => "You rock" else render 'edit', :alert => 'you roll' end end 

在控制器的更新方法中使用类似的东西。 很确定该方法也在Devise中。