Hartl的轨道教程6.3.4练习2,为什么新的指定名称保存?

时间:2017-11-04 06:37:02

标签: ruby-on-rails railstutorial.org

在本节中,我在数据中创建了一个用户,练习说通过分配新名称来更改用户名,然后使用save方法保存更改。

我这样做了,它返回了假。哈特尔问为什么它不起作用,我不知道为什么。我尝试使用以下命令在控制台中验证用户:

user.authenticate("foobar")

然后尝试更改名称,但user.save仍然返回false。

编辑:

我通过指定新名称来更改名称

user.name = "Harry Caray" 

但我相信我应该使用 user.update_attribute(:name," Big Lebowski")

user.save仍然返回false,但重新加载后,名称将被保存。

2 个答案:

答案 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方法有什么作用?

从简单的意义上讲,.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!)会引发异常。非爆炸版本不会:saveupdate返回false,而create仅返回对象。

     

请注意,如果将save作为参数传递,validate: false也可以跳过验证。应当谨慎使用此技术。

save(validate: false)

总结:

  • save-如果模型是新模型,则会在数据库中创建一条记录,否则将更新现有记录。运行验证,如果验证失败,则取消操作并保存返回false
  • save!-如果模型是新模型,则会在数据库中创建一条记录,否则将更新现有记录。运行验证,如果验证失败ActiveRecord::RecordInvalid
  • save(validate: false)-与save相同,但完全绕过了验证。