ruby-on-rails – 使用Devise和Omniauth编辑用户

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 使用Devise和Omniauth编辑用户前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在通过Railscast实施Devise和OmniAuth(与Devise documentation一起) – 目前,我有一个网站,访问者可以使用他们的Facebook帐户注册或填写表单.

不过,通过OmniAuth注册用户尝试编辑他们的个人资料时,遇到麻烦.当他们向他们的个人资料提交更改时,Devise会查找用户的当前密码,但用Facebook登录用户不知道他们的密码(它们在用户模型中自动设置):

  1. def self.find_for_facebook_oauth(auth,signed_in_resource=nil)
  2. user = User.where(:provider => auth.provider,:uid => auth.uid).first
  3. unless user
  4. 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]
  5. )
  6. end
  7. user
  8. end

用户编辑他的信息时,如果他通过OmniAuth设置了他的帐户,应该不需要密码确认.该教程建议方便的password_required方法将有助于我实现这一成果.具体来说,将此方法添加用户模型意味着如果用户没有通过OmniAuth注册,则该方法应该返回true(在这种情况下,provider属性将为nil):

  1. def password_required?
  2. super && provider.blank?
  3. end

因此,一段代码如:

  1. <%= form_for(resource,:as => resource_name,:url => registration_path(resource_name),:html => { :method => :put }) do |f| %>
  2. <%= devise_error_messages! %>
  3. <%= render :partial => "essential_user_info_inputs",:locals => { :f => f } %>
  4. <%= render :partial => "inessential_user_info_inputs",:locals => { :f => f } %>
  5. <% if f.object.password_required? %>
  6. <%= render :partial => "password_inputs",:locals => { :f => f } %>
  7. <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
  8. <%= f.password_field :current_password %>
  9. <% end %>
  10. <%= f.submit "Update" %>
  11. <% end %>

理论上只会在需要时显示密码输入.它还表明,Devise已经建立了逻辑,说OmniAuth用户不需要使用密码来编辑他们的帐户.我不知道如果这是真的,但教程的样子使它看起来像这样.但是当OmniAuth用户尝试编辑他的帐户时,我得到“当前密码不能为空”.与非OmniAuth用户相同(这是有道理的,因为密码字段也不会显示在这些用户的编辑页面上).

有些戳戳确认password_required?当用户通过OmniAuth注册并通过站点的常规用户注册时,方法返回false.即使我更改它只是运行超类方法,它返回false.

任何关于password_required方法发生什么的想法?我在任何地方找不到任何东西,但我觉得这是现在的事情.

更新:

这是现在工作,但不使用Railscast中概述的方法,它依赖于require_password?方法,一个我仍然不了解的话题.相反,我实施了here所示的here解决方案.所以我现在只需要密码来更新非OmniAuth帐户的代码

  1. class Users::RegistrationsController < Devise::RegistrationsController
  2. def update
  3. @user = User.find(current_user.id)
  4. email_changed = @user.email != params[:user][:email]
  5. is_facebook_account = !@user.provider.blank?
  6.  
  7. successfully_updated = if !is_facebook_account
  8. @user.update_with_password(params[:user])
  9. else
  10. @user.update_without_password(params[:user])
  11. end
  12.  
  13. if successfully_updated
  14. # Sign in the user bypassing validation in case his password changed
  15. sign_in @user,:bypass => true
  16. redirect_to root_path
  17. else
  18. render "edit"
  19. end
  20. end
  21. end

解决方法

最简单的方法是覆盖您的RegistrationsController中的update_resource方法.这是由设计人员自己实施的控制器建议的:
  1. # By default we want to require a password checks on update.
  2. # You can overwrite this method in your own RegistrationsController.
  3. def update_resource(resource,params)
  4. resource.update_with_password(params)
  5. end

因此,解决方案是在您自己的控制器中覆盖此方法,如下所示:

  1. class Users::RegistrationsController < Devise::RegistrationsController
  2.  
  3. # Overwrite update_resource to let users to update their user without giving their password
  4. def update_resource(resource,params)
  5. if current_user.provider == "facebook"
  6. params.delete("current_password")
  7. resource.update_without_password(params)
  8. else
  9. resource.update_with_password(params)
  10. end
  11. end
  12.  
  13. end

猜你在找的Ruby相关文章