Editing / updating a user not working when using has_secure_password in Rails 4

I use the Michael Hartl Ruby on Rails tutorial to create my own user authorization system. Everything works fine when creating a new user. When you try to update a user, this is when things no longer make sense. I am using the method has_secure_password. Therefore, I let him worry about taking the password and encrypting it. But when I update, there is some strange behavior.

An important role is that I can update the user without entering a password and confirming it. But if I enter the password and do not confirm, it requires confirmation. If I only enter a confirmation password, which is updated without errors. Now, since it has_secure_paasswordshould do this part, why doesn't it do it when updating? One thing that I have not added to my User model is to check for the presence of this line in the tutorial:

The presence check for the password and its confirmation is automatically added by has_secure_password.

I know that there are similar questions on this issue, but none of them provide strong parameters, and this is my guess why it does not work for me. Some of my codes are below.

User controller

def edit
    @user = User.find(params[:id])
end

def update
    @user = User.find(params[:id])

    # if params[:user][:password].blank?
    #   render 'edit'
    #   return
    # end

    if @user.update(user_params)
        redirect_to @user, notice: 'User successfully updated'
    else
        render 'edit', notice: 'Failed to update profile.'
    end
end
def user_params
    params.require(:user).permit(
        :username, :email, :phone, :bio, :password, :password_confirmation
        )
end

User model

class User < ActiveRecord::Base

  before_save {self.email = email.downcase}
  has_secure_password
  before_create :create_remember_token

  validates :username, presence: true, length: {maximum: 255, minimum: 5},
  format: { with: /\A[a-zA-Z0-9]*\z/, message: "may only contain letters and numbers." },
  uniqueness: true

  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }
  #... Other User stuff.

Change form

<div class="col-xs-8 col-xs-offset-2">
  <%= form_for(@user, :html => {:class => 'well'}) do |f| %>

    <div class="form-group">
      <%= f.label :username %><br />
      <%= f.text_field :username, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.label :phone %><br />
      <%= f.phone_field :phone, class: 'form-control' %>
    </div>


    <div class="form-group">
      <%= f.label :bio %><br />
      <%= f.text_area :bio, class: 'form-control' %> 
    </div>


    <div class="form-group">
      <%= f.label :email %><br />
      <%= f.email_field :email, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.label :password %><br />
      <%= f.password_field :password, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.label :password_confirmation %><br />
      <%= f.password_field :password_confirmation, class: 'form-control' %>
    </div>

    <div class="form-group">
      <%= f.submit "Update", class: 'btn btn-default' %>
    </div>
  <% end %>

</div>
+4
1

update create, .

ActiveModel:: SecurePassword:

, ( password_confirmation).

secure_password.rb

def has_secure_password(options = {})
  ...
  if options.fetch(:validations, true)
    validates_confirmation_of :password, if: lambda { |m| m.password.present? }
    validates_presence_of     :password, :on => :create
    validates_presence_of     :password_confirmation, if: lambda { |m| m.password.present? }
  end
  ...
end
+2

Source: https://habr.com/ru/post/1527381/


All Articles