Ruby-on-rails 为什么在保存对象后使用“重新加载”方法?(Hartl Rails Tut 6.30)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22259641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why use 'reload' method after saving object? (Hartl Rails Tut 6.30)
提问by sixty4bit
I'm working on the exercises for chapter 6 of Hartl's Rails 4 Tutorial. The first exercise tests to make sure that user email addresses are down-cased correctly:
我正在编写 Hartl 的 Rails 4 教程第 6 章的练习。第一个练习测试以确保用户电子邮件地址正确小写:
require 'spec_helper'
describe User do
.
.
.
describe "email address with mixed case" do
let(:mixed_case_email) { "[email protected]" }
it "should be saved as all lower-case" do
@user.email = mixed_case_email
@user.save
expect(@user.reload.email).to eq mixed_case_email.downcase
end
end
.
.
.
end
What I don't understand is why the 'reload' method is necessary here. Once @user.emailis set to the contents of mixed_case_emailand saved, aren't @user.reload.emailand @user.emailthe same thing? I took the reload method out just to try it and it didn't seem to change anything with the test.
我不明白的是为什么这里需要“重新加载”方法。一旦@user.email被设定为内容mixed_case_email并保存,不@user.reload.email和@user.email是一回事吗?我把 reload 方法拿出来尝试一下,它似乎没有改变任何测试。
What am I missing here?
我在这里缺少什么?
回答by Hardik
Yes in this case @user.reload.emailand @user.emailis the same thing. But it's good practice to use @user.reload.emailinstead of @user.emailto check what is exactly saved in the database i mean you don't know if you or someone add some code in after_save which changes it's value then it will not have effect on your tests.
在这种情况下是的,@user.reload.email并且@user.email是同一回事。但是使用@user.reload.email而不是@user.email检查数据库中确切保存的内容是一种很好的做法,我的意思是您不知道您或某人是否在 after_save 中添加了一些代码来更改它的值,那么它不会对您的测试产生影响。
EDIT:And also what you are checking is what's saved in the database so @user.reload.emailexactly reflects what's saved in database then @user.email
编辑:而且您正在检查的是数据库中保存的内容,因此@user.reload.email准确地反映了数据库中保存的内容@user.email
回答by Derrick Mar
In-Memory vs. Database
内存与数据库
It's important to understand the difference from in-memory and the database. Any ruby code you write is in-memory. For instance, whenever a query is executed, it creates a new in-memory object with the corresponding data from the database.
了解内存和数据库的区别很重要。您编写的任何 ruby 代码都在内存中。例如,每当执行查询时,它都会使用数据库中的相应数据创建一个新的内存对象。
# @student is a in-memory object representing the first row in the Students table.
@student = Student.first
Your example
你的榜样
Here is your example with comments for explanation
这是您的示例,并附有注释以供解释
it "should be saved as all lower-case" do
# @user is an in-memory ruby object. You set it's email to "[email protected]"
@user.email = mixed_case_email
# You persist that objects attributes to the database.
# The database stores the email as downcase probably due to a database constraint or active record callback.
@user.save
# While the database has the downcased email, your in-memory object has not been refreshed with the corresponding values in the database.
# In other words, the in-memory object @user still has the email "[email protected]".
# use reload to refresh @user with the values from the database.
expect(@user.reload.email).to eq mixed_case_email.downcase
end
To see a more thorough explanation see this post.
要查看更详尽的解释,请参阅此帖子。
回答by Satishakumar Awati
reload
Reloads the attributes of object(here @user) from the database. It always ensures object has latest data that is currently stored in database.
从数据库重新加载对象(此处为@user)的属性。它始终确保对象具有当前存储在数据库中的最新数据。
With this we can also avoid
有了这个我们也可以避免
ActiveRecord::StaleObjectError
This normally comes when we try to change old version of the object.
这通常发生在我们尝试更改对象的旧版本时。
回答by rails4guides.com
It should be the same thing. The whole point is that the reload method reloads the object from the database. Now you can check if your newly created test object is actually saved with the correct/expected attributes.
应该是一样的。重点是 reload 方法从数据库中重新加载对象。现在,您可以检查新创建的测试对象是否确实使用正确/预期的属性保存。
回答by Asarluhi
What the example wants to check is whether the before_savecallback in app/models/user.rbdoes its job. The before_savecallback should set every user's email to downcase before it is saved in the database, thus chapter 6 exercise 1 wants to test if its value in the database, that can be retrieved by using method reload, is effectively saved as downcase.
该示例要检查的是before_save回调是否app/models/user.rb完成其工作。该before_save回调应该在其之前被保存在数据库中,从而第6章练习1要测试其是否在数据库中的值,可以通过使用方法检索每个用户的电子邮件设置为downcase reload,有效地保存为downcase。

