Ruby on rails 使用Desive和Omniauth编辑用户

Ruby on rails 使用Desive和Omniauth编辑用户,ruby-on-rails,devise,ruby-on-rails-3.2,omniauth,Ruby On Rails,Devise,Ruby On Rails 3.2,Omniauth,我正在通过Railscast实施Desive和OmniAuth(以及Desive)——目前,我有一个网站,访问者可以使用他们的facebook帐户或填写表单注册 不过,当通过OmniAuth注册的用户试图编辑他们的个人资料时,我遇到了麻烦。Desive在用户提交个人资料更改时查找用户的当前密码,但那些使用facebook登录的用户不知道自己的密码(密码在用户模型中自动设置): 当用户编辑其信息时,如果他通过OmniAuth设置帐户,则应用程序不需要密码确认。教程建议您需要一个方便的密码?方法将帮

我正在通过Railscast实施Desive和OmniAuth(以及Desive)——目前,我有一个网站,访问者可以使用他们的facebook帐户或填写表单注册

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

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

因此,一段代码如下:

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
  <%= devise_error_messages! %>
    <%= render :partial => "essential_user_info_inputs", :locals => { :f => f } %>
    <%= render :partial => "inessential_user_info_inputs", :locals => { :f => f } %>
    <% if f.object.password_required? %> 
        <%= render :partial => "password_inputs", :locals => { :f => f } %>
        <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
        <%= f.password_field :current_password %>
    <% end %>
  <%= f.submit "Update" %>
<% end %>
resource\u name,:url=>registration\u path(resource\u name),:html=>{:method=>:put})do | f |%>
“基本用户信息输入”,:locals=>{:f=>f}%>
“非必要的用户信息输入”,:locals=>{:f=>f}%>
“密码输入”,:locals=>{:f=>f}%>
(我们需要您当前的密码来确认您的更改)
理论上仅在需要时显示密码输入。它还表明Deviate内置了这样一种逻辑,即OmniAuth用户不需要使用密码来编辑他们的帐户。我不知道这是不是真的,但是教程让它看起来像那样。但当OmniAuth用户试图编辑其帐户时,我会得到“当前密码不能为空”。非OmniAuth用户也是如此(这很有意义,因为这些用户的编辑页面上也不会显示密码字段)

有人四处打探确认密码是必需的吗?方法在用户通过OmniAuth和站点的常规用户注册时返回false。即使我将其更改为只运行超类方法,它也会返回false

你知道密码所需的方法是怎么回事吗?我在任何地方都找不到关于它的任何东西,但我觉得这正是让事情变得一团糟的原因

更新: 这项工作正在进行中,但没有使用Railscast中概述的方法,该方法依赖于requires\u password?方法,一个我仍然一无所知的话题。相反,我按照建议实施了概述的解决方案。因此,我现在只需要密码就可以用以下代码更新非OmniAuth帐户:

class Users::RegistrationsController < Devise::RegistrationsController
def update
    @user = User.find(current_user.id)
    email_changed = @user.email != params[:user][:email]
    is_facebook_account = !@user.provider.blank?

    successfully_updated = if !is_facebook_account
      @user.update_with_password(params[:user])
    else
      @user.update_without_password(params[:user])
    end

    if successfully_updated
      # Sign in the user bypassing validation in case his password changed
      sign_in @user, :bypass => true
      redirect_to root_path
    else
      render "edit"
    end
  end
end
类用户::注册控制器<设计::注册控制器
def更新
@user=user.find(当前用户id)
email_changed=@user.email!=参数[:用户][:电子邮件]
这是facebook账户吗@user.provider.blank?
成功更新=如果!是facebook账户吗
@用户。使用密码更新用户(参数[:用户])
其他的
@user.update_而不使用_密码(参数[:user])
结束
如果成功更新
#如果用户的密码发生更改,请绕过验证登录该用户
在@user中签名:旁路=>true
将\重定向到根\路径
其他的
渲染“编辑”
结束
结束
结束

我在什么地方看到过这个


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

在控制器的更新方法中使用类似的方法。非常确定该方法也存在于Desive中。

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


最简单的方法是覆盖注册控制器中的更新资源方法。这是由Desive在其自己的控制器实施中提出的建议:

  # 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
类用户::注册控制器<设计::注册控制器
#覆盖更新_资源,允许用户在不提供密码的情况下更新其用户
def更新_资源(资源,参数)
如果当前_user.provider==“facebook”
参数删除(“当前密码”)
资源。在不使用密码的情况下更新\u(参数)
其他的
资源。使用\u密码更新\u(参数)
结束
结束
结束

您应该始终尝试查找gem的wiki页面。这是迪安的:。下面是您尝试执行的操作:这些参数[:user].delete不需要,因为OP将这些字段隐藏在表单中,因此它们永远不会被发送。听起来不错。我会更新我偷来的代码,看看你是否正确。代码越少越好。简单明了!。很好用。这正是我要找的那件丢失的东西。工作很好。我还在
update\u resource
方法上方添加了
protected
,并更新了使用controller
design\u的路线:用户,控制器:{omniauth\u回调:“用户/omniauth\u回调”,注册:'users/registrations'}
,我认为
当前用户.provider==“facebook”
应该是
resource.provider==“facebook”
当前用户并不总是可用。例如,如果用户被称为
current\u login
current\u user\u login
resource
方法被解析为当前的
@request.env['design.mapping']
。也许答案值得改变
  # 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