ruby on rails - ¿Por qué usar el método de "recargar" después de guardar el objeto?(Hartl Rails Tut 6.30)
ruby-on-rails methods (5)
En memoria contra base de datos
Es importante entender la diferencia entre la memoria y la base de datos. Cualquier código de rubí que escriba está en la memoria. Por ejemplo, cada vez que se ejecuta una consulta, crea un nuevo objeto en memoria con los datos correspondientes de la base de datos.
# @student is a in-memory object representing the first row in the Students table.
@student = Student.first
Tu ejemplo
Aquí está su ejemplo con comentarios para la explicación
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
Para ver una explicación más completa, mira esta post .
Estoy trabajando en los ejercicios para el capítulo 6 del Tutorial de Hartl''s Rails 4. El primer ejercicio evalúa para asegurarse de que las direcciones de correo electrónico de los usuarios se envían correctamente:
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
Lo que no entiendo es por qué el método de ''recargar'' es necesario aquí. Una vez que @user.email
se establece en los contenidos de mixed_case_email
y se guarda , ¿no son @user.reload.email
y @user.email
lo mismo? Tomé el método de recarga solo para probarlo y no pareció cambiar nada con la prueba.
¿Que me estoy perdiendo aqui?
Debería ser lo mismo. El punto es que el método de recarga vuelve a cargar el objeto de la base de datos. Ahora puede verificar si su objeto de prueba recientemente creado se guarda con los atributos correctos / esperados.
Lo que el ejemplo quiere comprobar es si la devolución de llamada before_save
en la app/models/user.rb
hace su trabajo. La before_save
llamada before_save
debe establecer el correo electrónico de cada usuario en downcase antes de que se guarde en la base de datos, así el capítulo 6 exercise 1 quiere probar si su valor en la base de datos, que puede recuperarse usando reload
método, se guarda efectivamente como downcase.
Sí, en este caso @user.reload.email
y @user.email
es lo mismo. Pero es una buena práctica usar @user.reload.email
lugar de @user.email
para verificar qué se guardó exactamente en la base de datos, quiero decir que no sabe si usted o alguien agrega algún código en after_save que cambia su valor, entonces lo hará no tendrá efecto en tus pruebas
EDITAR: Y también lo que está comprobando es lo que se guarda en la base de datos para que @user.reload.email
refleje exactamente lo que se guarda en la base de datos luego @user.email
reload
Recarga los atributos de objeto (aquí @user) de la base de datos. Siempre garantiza que el objeto tenga los últimos datos que están almacenados actualmente en la base de datos.
Con esto también podemos evitar
ActiveRecord::StaleObjectError
Esto normalmente ocurre cuando intentamos cambiar la versión anterior del objeto.