0

我有一个从头开始的身份验证系统,当用户单击“编辑配置文件”时,无论他想编辑哪个字段,都必须输入当前密码。

def update
  if params[:user][:password].present?
    authenticated = @user.authenticate(params[:user][:current_password])
    if authenticated && @user.update(user_params)
      redirect_to root_url
      flash[:notice] = "Your profile was successfully updated!"
    else
      @user.errors.add(:current_password, 'is invalid') unless authenticated
      render :edit
    end
  elsif @user.update(user_params)
    redirect_to root_url
    flash[:notice] = "Your profile was successfully updated!"
  else
    render :edit
  end
end

当用户想要更改他的密码时,我如何才能调用身份验证或使用某些上下文模型验证?

4

2 回答 2

1

我不建议将此逻辑混入模型中,因为随着应用程序随着时间的推移而增长,您最终会遇到难以遵循的复杂性。

尝试查看表单对象:

我会实现这样的事情:

class UserUpdateForm
  include ActiveModel::Model

  # Attributes
  attr_accessor :user, :new_password, :new_password_confirmation

  # Validations
  validates :current_password, if: :new_password
  validate :authenticate, if: :current_password
  validates :new_password, confirmation: true, allow_blank: true

  def initialize(user)
    self.user = user
  end

  def submit(params)
    self.new_password = params[:new_password]
    self.new_password_confirmation = params[:new_password_confirmation]

    if self.valid?
      # Set other attributes as needed, then set new password below.
      self.user.password = self.new_password if self.new_password.present?
      self.user.save
    else
      false
    end
  end

private

  def authenticate
    unless self.authenticate(self.current_password)
      self.errors.add(:current_password, 'is invalid')
    end
  end
end

然后你可以像这样从你的控制器调用它:

def update
  @user_update_form = UserUpdateForm.new(@user)

  if @user_update_form.submit(params)
    flash[:notice] = "Your profile was successfully updated!"
    redirect_to root_url
  else
    render :edit
  end
end

请参阅上面的链接以了解如何处理视图等。这只是为了让你开始。

于 2015-05-20T15:47:29.120 回答
0

您可以在此操作语句中创建一个嵌套的 if-else,它将检查对象中是否存在new_passwordnew_password_confirmation(或任何新密码和确认字段被调用)params[:user]。如果它们存在 - 您可以重定向到某些页面之王并请求输入现有密码。

另一种方法是使用 ajax 以异步方式显示具有相同请求的对话框(如 respond_with 处理该请求的自调用 javascript 函数)。然后在控制器的其他操作中处理对话框中的提交按钮。

更新(考虑使用验证器):

考虑到验证,您可以编写自己的验证器(用于密码)和条件来检查新密码字段何时带有来自客户端的一些数据。

我认为它可能看起来像这样:

validate :password_update?

def password_update?
    if new_password.present?
        if current_password !== self.password
          errors.add(:current_password, "must be supplied!")
        else
            # update data and password
        end
    else
        # do your regular update
    end
end
于 2015-05-20T15:26:52.823 回答