你的问题的答案是,User.create
返回一个User
实例如果成功or失败。如果由于验证而失败,则该实例将无效并出现错误:
user.valid? # <= returns false
user.errors.count # <= will be > 0
user.errors.blank? # <= will be false
所以你的代码将从此改变:
if user==false or user==nil or user==vals
to this:
if !user.valid?
您还可以使用此模式:
user.attributes = vals
if user.save
... save succeeded ...
else
... save failed ...
end
The save
方法返回一个布尔值true
or false
因为您是在现有实例上调用它。
但是,让我们通过其他几种方式让您走上正确的道路:
First:你有这个:
if User.exists(vals[:username])
(我假设exits
是你放在你的方法上User
模型,因为这不是 Rails 的事情)。您可以在模型上使用另一个验证,而不是在控制器中进行检查:
class User < ActiveRecord::Base
...
validates :username, unique: true
...
end
现在,当您尝试创建用户时,如果您已有同名用户,验证将会失败。
Second:你有这个:
vals[:create_date] = DateTime.current
这是不必要的。如果您向模型添加一列名为created_at
它将自动保存创建日期(由 ActiveRecord 管理)。您可以添加它及其伙伴updated_at
迁移到您的模型中,如下所示:
create_table :users do |t|
...
t.timestamps # <= tells rails to add created_at and updated_at
end
或者,既然你已经有一个users
table:
add_column :users, :created_at, :datetime
add_column :users, :updated_at, :datetime
现在,您将始终拥有用户模型的创建日期/时间和上次更新,而无需额外的代码。
Third:你有这个:
user = User.create(vals, :without_protection => :true)
不要这样做。相反,改变这个:
vals = params[:user]
To this:
vals = params.require(:user).permit(:username, :password, :password_confirmation)
然后继续保护:
user = User.create(vals)
您可以将您想要从表单中添加的任何其他列添加到permit()
称呼。这一点非常重要,因为这种事情以后很难修复。 “一旦走上黑暗之路,它就将永远主宰你的命运。”
Fourth:您不应该重定向到user_path
如果保存失败,因为不会显示用户模型。相反,你应该重新渲染你的new
形式。您也不需要错误的闪现消息。如果new
表单呈现,它可以检查@user.errors
并报告相应的错误消息。请参阅ActiveRecord 错误对象文档 http://api.rubyonrails.org/classes/ActiveModel/Errors.html.
Finally:您提到即使您的密码已正确确认,您的验证也会失败。如果没有看到您的表单代码,我无法确定,但请确保您的密码字段被调用password
确认字段称为password_confirmation
。 Rails 正在寻找这个*_confirmation
特别是在验证确认时的字段值。
如果这不起作用,请发布您的表单代码,我会修改。