Allowing users to edit accounts without saving pas

2019-02-11 09:00发布

问题:

I am working on a ROR app, and I'm stuck when it comes to Devise and password confirmation. I'd like for my users to be able to edit their information (name, location, etc) without having to enter and confirm their password (that is unless they decide to change their password, in which case, these fields would be required.)

I did a bit of reading when it comes to devise and I noticed that this is a common issue. Unfortunately, I tried all of the solutions posted on the devise GitHub repo, but was unable to address my issue.

I have however, discovered a workaround, but am having an issue with what I hope will be the final step. Here is a small snippet of what my players.rb file looks like (I have two set's of accounts -- players and owners):

 has_one :account, :as => :profile

 accepts_nested_attributes_for :account, :reject_if => proc { |attributes| attributes['password'].blank? }

my accounts.rb file looks like this:

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :invited_by, :invited_by_id

As it's set up right now, the players can edit their profile without having to enter a password unless they are trying to edit the :password field -- this is excellent, and my desired result. However, I am running into a small snag... the :reject_if => proc { |attributes| attributes['password'].blank? } executes even when there is a new account (player) being created! This means if a player does not enter a password, instead of prompting him to enter a password, the application brakes!

I need some help writing an if statement or some condition that would basically only trigger the reject_if conditions if the Account belongs to a registered (existing) player.

I have tried: :reject_if => proc { |attributes| attributes['password'].blank? unless Player.new}

and

if Player.new
accepts_nested_attributes_for :account
else
accepts_nested_attributes_for :account, :reject_if => proc { |attributes| attributes['password'].blank? }
end

I cant seem to figure this out, so I decided to see if anyone could offer an opinion or advice. As always, I am extremely grateful for your time and any help you may offer. Thank you!

回答1:

Try this peace of code while updating user in controller. This is update method for devise version 1.5.3, these two lines will do the trick.

 def update
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)

    params[:user].delete(:password) if params[:user][:password].blank?
    params[:user].delete(:password_confirmation) if params[:user][:password_confirmation].blank?

    if resource.update_attributes(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


回答2:

I had this issue dog me for a long time. Solved it by following the "How To" then added :current_password to attr_accessible and created an attr_accessor with the following:

attr_accessor :password, :password_confirmation, :current_password
attr_accessible :email, :password, :password_confirmation, :remember_me, :username, :current_password

In case anyone else runs into this issue, here are the relavent links that helped me out:

1) How To: Allow users to edit their account without providing a password

2) Can't resolve "Current password can't be blank" when editing user

3) Problems trying' to update the user profile info without password (this is the one that solved it for me)

Also, here's a lead on how to do the same with Facebook via Devise & Omniauth:

4) Editing Users With Devise and Omniauth