ruby-on-rails methods ruby-on-rails-4 railstutorial.org

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.