创建失败时,Ruby on Rails Active Record 返回值?

2024-03-18

我是 ruby​​ on Rails 的新手,在完成这项工作时遇到困难。基本上我有一个用户注册页面,其中有密码确认。在 User 类中,我进行了以下验证:

validates :password, confirmation: true

在控制器中我有

def create
    vals = params[:user]
    if(User.exists(vals[:username])) 
        flash[:warning] = "#{vals[:username]} already exists! Please try a new one. "
    else
        vals[:create_date] = DateTime.current
        user = User.create(vals, :without_protection => :true)
        if user==false or user==nil or user==vals
            flash[:warning] = "#{vals[:username]} has not been registered successfully. "
        else
            flash[:notice] = "#{vals[:username]} has been registered. "
        end
    end
    redirect_to users_path
end

问题是,当密码与确认相符时,我仍然收到显示注册成功的通知消息。正如你所看到的,我尝试了几个返回值create但他们似乎都没有成功。我非常确定验证正在工作,因为如果密码与确认不匹配,我将无法看到刚刚创建的用户。另外,当我使用create!,我可以看到网站因验证错误而崩溃。谁能帮我告诉我什么create当记录未经验证时应该返回吗?

Thanks.


你的问题的答案是,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特别是在验证确认时的字段值。

如果这不起作用,请发布您的表单代码,我会修改。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建失败时,Ruby on Rails Active Record 返回值? 的相关文章

随机推荐