在本节中,我在数据中创建了一个用户,练习说通过分配新名称来更改用户名,然后使用save方法保存更改。
我这样做了,它返回了假。哈特尔问为什么它不起作用,我不知道为什么。我尝试使用以下命令在控制台中验证用户:
user.authenticate("foobar")
然后尝试更改名称,但user.save仍然返回false。
编辑:
我通过指定新名称来更改名称
user.name = "Harry Caray"
但我相信我应该使用 user.update_attribute(:name," Big Lebowski")
user.save仍然返回false,但重新加载后,名称将被保存。
答案 0 :(得分:0)
您可以通过检查模型错误来了解原因 - 例如
user.name = "new name"
@error_object = user.save
@error_object.errors.full_messages
答案 1 :(得分:0)
从新的rails控制台开始,假设您已经在数据库中拥有一个用户,我们可以将其分配给如下所示的本地变量:
> user = User.find_by(email: "mhartl@example.com")
现在,内存中有一个User
对象,它是数据库中用户的副本。我们可以通过以下方式确认这一点:
> user
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2018-08-16 05:57:13", updated_at: "2018-08-16 06:15:04", password_digest: "$2a$10$bS2s/24d3ePLscZ8iT/NheDAvOZmODKjbCV5groq4v5...">
现在,我们更改用户对象的名称:
> user.name = "Ace Ventura"
=> "Ace Venutura"
但是,如果我们尝试保存此用户,它将失败:
> user.save
=> false
然后我们可以检查错误消息:
> user.errors.messages
=> {:password=>["can't be blank", "is too short (minimum is 6 characters)"]}
在哈特尔(Hartl)的书section 6.2.4的练习2中,他问我们为什么打电话给.save
无效。它不起作用的原因是验证失败。在app/models/user.rb
的用户模型中,我们特别声明为了将用户添加到数据库中,应执行验证检查以确保用户对象的password
字符串至少为长度为6个字符。如果我们检查用户对象中是否有password
字符串,则会得到以下结果:
> user.password
=> nil
然后我们需要做的就是输入我们在本章前面提供的密码,然后我们将能够呼叫.save
:
> user.password = "foobar"
=> "foobar"
> user.save
=> true
现在,我们可以检查以确保数据库已正确更新:
> User.find_by(email: "mhartl@example.com").name
=> "Ace Ventura"
我上面给出的更新数据库条目的方法不是不是。Hartl在问题3中指的是“技术”。我提供了这一部分来解释验证的过程。当哈特尔(Hartl)提到“技术”时,他是在暗示您应该这样做:
> user.update_attribute(:name, "El Duderino")
=> true
(请注意,此处我们使用的是update_attribute
,而不是{strong>复数版本。update_attributes
。)正如Hartl在section 6.1.5中解释的那样,当我们只需要更新一个单个属性和同时跳过验证,我们应该使用update_attribute
。
从简单的意义上讲,.authenticate
方法所做的只是回答以下问题:“如果我向用户对象提供了此密码,我是否可以将对象保存到数据库?”因此,当我们这样做时:
> user.authenticate("not_the_right_password")
=> false
此处所有authenticate
都在告诉我们,如果设置user.password = "not_the_right_password"
,则在调用.save
时它将失败,因为我们输入的密码错误。它实际上并不会改变对象本身的任何内容。
save!
呢?引用the docs:
有许多方法可以更改数据库中对象的状态。有些方法将触发验证,但有些则不会。这意味着如果您不小心,有可能以无效状态将对象保存在数据库中。
以下方法触发验证,并且仅在对象有效时才将对象保存到数据库中:
create
create!
save
save!
update
update!
如果记录无效,则爆炸版本(例如
save!
)会引发异常。非爆炸版本不会:save
和update
返回false
,而create
仅返回对象。请注意,如果将
save
作为参数传递,validate: false
也可以跳过验证。应当谨慎使用此技术。save(validate: false)
总结:
save
-如果模型是新模型,则会在数据库中创建一条记录,否则将更新现有记录。运行验证,如果验证失败,则取消操作并保存返回false
。save!
-如果模型是新模型,则会在数据库中创建一条记录,否则将更新现有记录。运行验证,如果验证失败ActiveRecord::RecordInvalid
。save(validate: false)
-与save
相同,但完全绕过了验证。