Зачем использовать метод 'reload' после сохранения объекта? (Hartl Rails Tut 6.30)
Я работаю над упражнениями для Главы 6 руководства по Rails 4 Хартла. Первое упражнение тесты, чтобы убедиться, что адреса электронной почты пользователя в нижнем регистре правильно:
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
то же самое? Я взял метод перезагрузки, чтобы попробовать его, и, похоже, ничего не изменилось с тестом.
что я пропустила?
5 ответов
да, в данном случае @user.reload.email
и @user.email
это одно и то же. Но это хорошая практика, чтобы использовать @user.reload.email
вместо @user.email
чтобы проверить, что именно сохранено в базе данных, я имею в виду, что вы не знаете, добавляете ли вы или кто-то код в after_save, который изменяет его значение, тогда он не будет влиять на ваши тесты.
EDIT:
А также то, что вы проверяете, это то, что сохранено в базе данных so @user.reload.email
точно отражает то, что сохранено в базе данных, то @user.email
в памяти против базы данных
важно понимать разницу между памятью и базой данных. Любой код ruby, который вы пишете, находится в памяти. Например, при выполнении запроса создается новый объект в памяти с соответствующими данными из базы данных.
# @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
обычно это происходит, когда мы пытаемся изменить старую версию объекта.
Это должно быть то же самое. Все дело в том, что метод reload перезагружает объект из базы данных. Теперь вы можете проверить, действительно ли ваш вновь созданный тестовый объект сохранен с правильными/ожидаемыми атрибутами.
какой пример хочет проверить, является ли before_save
обратный вызов в app/models/user.rb
делает свою работу. The before_save
обратный вызов должен установить каждый адрес электронной почты пользователя в downcase, прежде чем он будет сохранен в базе данных, таким образом, Глава 6 Упражнение 1 хочет проверить, если его значение в базе данных, которые могут быть получены с помощью метода reload
, эффективно сохраняется как downcase.