user.save 在控制台中返回 false,但通过 UI 完成时返回 true

Posted

技术标签:

【中文标题】user.save 在控制台中返回 false,但通过 UI 完成时返回 true【英文标题】:user.save returns false in console, but true when done via the UI 【发布时间】:2016-03-03 09:24:53 【问题描述】:

我是一名编程/rails 初学者,遇到了一个我无法理解的错误。

我正在使用/学习“has_secure_password”方法。当我尝试在控制台中使用不匹配的密码/确认密码创建用户时,控制台返回 false 并且错误是“密码确认与密码不匹配”。但是,当我尝试在给定以下代码(+ 视图)的 UI 中做同样的事情时,它保存得很好!现在,请注意,在我的“user_params”方法中,我不小心忘记了允许“:password_confirmation”,这就是我首先注意到这个问题的原因。添加了 ":password_confirmation" 后,视图会引发错误,但这不是重点。为什么即使没有这个,新的用户记录也会成功创建,但密码和密码确认不匹配,即使它没有保存在控制台中?

这是我的用户模型:

class User < ActiveRecord::Base
  has_secure_password

  validates :name, presence: true
  validates :email, presence: true, format: /\A\S+@\S+\z/, uniqueness: case_sensitive: false
  validates :password, length: minimum: 4, allow_blank: true
end

还有我的用户控制器:

class UsersController < ApplicationController
def index
    @users = User.all
end

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

def new
    @user = User.new
end

def create
    @user = User.new(user_params)
    if @user.save
        redirect_to @user, notice: "Thanks for signing up!"
    else
        render :new
    end
end

private
def user_params
    params.require(:user).permit(:name, :email, :password)
end
end

【问题讨论】:

【参考方案1】:

这是因为 password_confirmation 属性是可选的。当它没有提供给 has_secure_password 的模型时,模型只接受密码。

当您的密码确认属性未通过 user_params 在控制器中列入白名单时,它根本不会被传递给模型,这就是 mismatches 似乎不会引发错误的原因。事实上,验证根本没有发生。

这适用于您的控制台,因为它无需控制器或强参数白名单即可创建用户。

【讨论】:

这真的很有帮助,谢谢。但后续问题:作为用户,我应该能够根本不提供密码确认,并且仍然应该创建记录,因为它是“可选的”。那么我的代码(假设我将 password_confirmation 列入白名单)使这个字段也是必需的呢?许可不同于要求,对吧?因此,当所有内容都在控制器中列入白名单时,它现在正确地抛出错误,但现在我不明白为什么! 如果将其添加到表单中,则在提交表单时,password_confirmation 的值将为空,并且验证失败。 只需验证您的用户模型中是否存在 password_confirmation。

以上是关于user.save 在控制台中返回 false,但通过 UI 完成时返回 true的主要内容,如果未能解决你的问题,请参考以下文章

尽管此 JSON 有数据,但方法返回 JSON“empty:false”

ASP.NET @Html.DropDownListFor() 选择的值设置为 true 但提交给控制器时返回 false

我们啥时候应该使用 save() 的高级参数?

gitlab管理员账号密码忘记怎么办?

在 grails 控制器中模拟命令对象导致 hasErrors() 无论如何都返回 false !请帮忙

Social.localUser.Authenticate 在 Unity 中每次都返回 false