【问题标题】:Editing/Updating user not working when using has_secure_password in Rails 4在 Rails 4 中使用 has_secure_password 时编辑/更新用户不起作用
【发布时间】:2014-03-17 08:33:05
【问题描述】:

我正在使用 Michael Hartl 的 Ruby on Rails tutorial 来制作我自己的用户身份验证系统。创建新用户时一切正常。当尝试更新用户时,事情不再有意义。我正在使用has_secure_password 方法。所以我让它担心获取密码和加密它。但是当我更新时,会发生一些奇怪的行为。

重要的部分是我可以在不输入任何密码及其确认的情况下更新用户。但是如果我输入密码并且没有确认,则需要确认。如果我只输入确认密码,则更新不会出错。现在既然has_secure_paassword 应该做那部分,为什么更新时不做呢?由于教程中的这一行,我没有在我的用户模型中添加的一件事是存在验证:

密码的存在验证及其确认是 由 has_secure_password 自动添加。

我知道对此有类似的问题,但似乎没有一个强制执行强参数,这是我对它为什么不适合我的猜测。下面是我的一些代码。

用户控制器

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

用户模型

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.

编辑表单

<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>

【问题讨论】:

  • 您可以将用户表单视图添加到您的问题中吗?可能是app/views/user/_form.html.erb@Andy
  • @franksort 我补充说。但是我尝试了一些不同的东西,因为我包含了报价。 has_secure_password 似乎没有按照教程所说的那样做。至少在更新方面。创建新用户时工作正常。但是在更新时,它似乎无法识别密码存在验证。
  • 感谢您抽出宝贵的时间@franksort,但如果我将:password_digest 添加到强参数中将不起作用:/

标签: ruby-on-rails-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

【讨论】:

  • 哇哦。所以我明白了。是的,这确实回答了为什么会发生的问题。非常感谢你的帮助。有没有办法覆盖它,所以它也发生在 update 动作中?我对 Rails 还是很陌生 :)
  • @Andy 很高兴我能帮上忙! User 模型中的 validates :password, presence: true, if: Proc.new { |user| user.password.present? }, confirmation: true, on: :update 之类的东西可能会起作用。
猜你喜欢
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
相关资源
最近更新 更多