six*_*bit 29 methods ruby-on-rails railstutorial.org ruby-on-rails-4
我正在为Hartl的Rails 4 Tutorial的第6章练习.第一个练习测试以确保用户电子邮件地址正确缩小:
require 'spec_helper'
describe User do
.
.
.
describe "email address with mixed case" do
let(:mixed_case_email) { "Foo@ExAMPle.CoM" }
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
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这里需要'重载'方法.一旦@user.email被设定为内容mixed_case_email并保存,不@user.reload.email和@user.email是一回事吗?我把重装方法拿出去尝试它并且似乎没有改变测试的任何东西.
我在这里错过了什么?
Har*_*dik 34
在这种情况下是的@user.reload.email,@user.email是一回事.但是使用@user.reload.email而不是@user.email检查数据库中确切保存的内容是一种很好的做法,我的意思是你不知道你或者是否有人在after_save中添加一些代码来改变它的值,那么它对你的测试没有影响.
编辑:
你正在检查的是数据库中保存的是什么,所以@user.reload.email准确地反映了数据库中保存的内容@user.email
Der*_*Mar 25
了解内存和数据库的区别非常重要.您编写的任何ruby代码都在内存中.例如,每当执行查询时,它都会使用数据库中的相应数据创建一个新的内存中对象.
# @student is a in-memory object representing the first row in the Students table.
@student = Student.first
Run Code Online (Sandbox Code Playgroud)
以下是您的解释说明示例
it "should be saved as all lower-case" do
# @user is an in-memory ruby object. You set it's email to "Foo@ExAMPle.CoM"
@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 "Foo@ExAMPle.CoM".
# use reload to refresh @user with the values from the database.
expect(@user.reload.email).to eq mixed_case_email.downcase
end
Run Code Online (Sandbox Code Playgroud)
要查看更详尽的解释,请参阅此帖子.
reload
Run Code Online (Sandbox Code Playgroud)
从数据库重新加载对象(此处为@user)的属性.它始终确保对象具有当前存储在数据库中的最新数据.
有了这个,我们也可以避免
ActiveRecord::StaleObjectError
Run Code Online (Sandbox Code Playgroud)
这通常是在我们尝试更改旧版本的对象时.