为什么在保存对象后使用"重新加载"方法?(哈特尔轨道图6.30)



我正在研究Hartl's Rails 4教程第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

我不明白的是为什么在这里需要"重新加载"方法。一旦将@user.email设置为mixed_case_email保存的内容,@user.reload.email@user.email不是同一件事吗?我拿出了重新加载方法只是为了尝试它,但它似乎并没有改变测试。

我在这里缺少什么?

是的,在这种情况下, @user.reload.email@user.email是同一件事。但是,最好使用@user.reload.email而不是@user.email检查数据库中的确切保存的内容,我的意思是您不知道您或某人是否在after_save中添加了一些代码,哪些更改其值的代码将对您的测试没有影响。<<<<<<<<

编辑:而且您要检查的是保存在数据库中的内容,因此@user.reload.email完全反映了保存在数据库中的内容,然后反映了@user.email

内存与数据库

了解与内存和数据库的差异很重要。您编写的任何红宝石代码都是内存的。例如,每当执行查询时,它都会创建一个新的内存对象,并使用数据库中的相应数据。

# @student is a in-memory object representing the first row in the Students table.
@student = Student.first

您的示例

这是您的示例,有说明的评论

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

要查看更彻底的解释,请参阅此帖子。

reload 

从数据库中重新加载对象的属性( @user)。它始终确保对象具有当前存储在数据库中的最新数据。

这样我们也可以避免

ActiveRecord::StaleObjectError

通常,当我们尝试更改对象的旧版本时。

应该是同一件事。重点是重新加载方法从数据库中重新加载对象。现在,您可以检查新创建的测试对象是否实际上使用正确的/预期属性保存。

示例要检查的是什么是app/models/user.rb中的before_save回调是否可以完成其作业。before_save回调应在保存在数据库中之前将每个用户的电子邮件设置为Dowscase,因此第6章练习1希望测试其在数据库中是否可以通过使用方法reload来检索其值,并可以将其保存为跌倒。

最新更新