1 Consejos Generales
Antes de intentar actualizar una aplicación existente, debe asegurarse de tener una buena razón para hacerlo. Necesita equilibrar varios factores: la necesidad de nuevas funciones, la dificultad creciente de encontrar soporte para el código antiguo y su tiempo y habilidades disponibles, por nombrar algunos.
1.1 Cobertura de Pruebas
La mejor manera de asegurarse de que su aplicación aún funcione después de la actualización es tener una buena cobertura de pruebas antes de comenzar el proceso. Si no tiene pruebas automatizadas que ejerciten la mayor parte de su aplicación, necesitará dedicar tiempo a ejercitar manualmente todas las partes que hayan cambiado. En el caso de una actualización de Rails, eso significará cada pieza de funcionalidad en la aplicación. Hágase un favor y asegúrese de que su cobertura de pruebas sea buena antes de comenzar una actualización.
1.2 Versiones de Ruby
Rails generalmente se mantiene cerca de la última versión de Ruby lanzada cuando se publica:
- Rails 7.2 requiere Ruby 3.1.0 o más reciente.
- Rails 7.0 y 7.1 requieren Ruby 2.7.0 o más reciente.
- Rails 6 requiere Ruby 2.5.0 o más reciente.
- Rails 5 requiere Ruby 2.2.2 o más reciente.
Es una buena idea actualizar Ruby y Rails por separado. Actualice primero a la última versión de Ruby que pueda, y luego actualice Rails.
1.3 El Proceso de Actualización
Al cambiar versiones de Rails, es mejor moverse lentamente, una versión menor a la vez, para hacer un buen uso de las advertencias de desaprobación. Los números de versión de Rails están en la forma Mayor.Menor.Parche. Las versiones Mayor y Menor pueden hacer cambios en la API pública, por lo que esto puede causar errores en su aplicación. Las versiones de Parche solo incluyen correcciones de errores y no cambian ninguna API pública.
El proceso debería ser el siguiente:
- Escriba pruebas y asegúrese de que pasen.
- Pase a la última versión de parche después de su versión actual.
- Corrija las pruebas y las características desaprobadas.
- Pase a la última versión de parche de la siguiente versión menor.
Repita este proceso hasta alcanzar su versión objetivo de Rails.
1.3.1 Cambiando entre versiones
Para cambiar entre versiones:
- Cambie el número de versión de Rails en el
Gemfile
y ejecutebundle update
. - Cambie las versiones de los paquetes JavaScript de Rails en
package.json
y ejecutebin/rails javascript:install
si está ejecutando jsbundling-rails. - Ejecute la tarea de actualización.
- Ejecute sus pruebas.
Puede encontrar una lista de todos los gems de Rails lanzados aquí.
1.4 La Tarea de Actualización
Rails proporciona el comando rails app:update
. Después de actualizar la versión de Rails en el Gemfile
, ejecute este comando. Esto le ayudará con la creación de nuevos archivos y cambios de archivos antiguos en una sesión interactiva.
$ bin/rails app:update
exist config
conflict config/application.rb
Overwrite /myapp/config/application.rb? (enter "h" for help) [Ynaqdh]
force config/application.rb
create config/initializers/new_framework_defaults_7_2.rb
...
No olvide revisar la diferencia, para ver si hubo algún cambio inesperado.
1.5 Configurar Valores Predeterminados del Framework
La nueva versión de Rails podría tener diferentes valores de configuración predeterminados que la versión anterior. Sin embargo, después de seguir los pasos descritos anteriormente, su aplicación aún se ejecutará con los valores predeterminados de configuración de la versión de Rails anterior. Esto se debe a que el valor de config.load_defaults
en config/application.rb
aún no se ha cambiado.
Para permitirle actualizar a nuevos valores predeterminados uno por uno, la tarea de actualización ha creado un archivo config/initializers/new_framework_defaults_X.Y.rb
(con la versión deseada de Rails en el nombre del archivo). Debe habilitar los nuevos valores de configuración descomentándolos en el archivo; esto se puede hacer gradualmente en varios despliegues. Una vez que su aplicación esté lista para ejecutarse con los nuevos valores predeterminados, puede eliminar este archivo y cambiar el valor de config.load_defaults
.
2 Actualización de Rails 7.1 a Rails 7.2
Para obtener más información sobre los cambios realizados en Rails 7.2, consulte las notas de lanzamiento.
2.1 Todas las pruebas ahora respetan la configuración active_job.queue_adapter
Si ha configurado config.active_job.queue_adapter
en su archivo config/application.rb
o config/environments/test.rb
, el adaptador que seleccionó anteriormente no se usaba de manera consistente en todas las pruebas. En algunas pruebas se utilizaba su adaptador, pero en otras se utilizaba el TestAdapter
.
En Rails 7.2, todas las pruebas respetarán la configuración de queue_adapter
si se proporciona. Esto puede causar errores en las pruebas si había configurado queue_adapter
en algo distinto de :test
, pero había escrito pruebas de una manera que dependía del TestAdapter
.
Si no se proporciona ninguna configuración, se seguirá utilizando el TestAdapter
.
3 Actualización de Rails 7.0 a Rails 7.1
Para obtener más información sobre los cambios realizados en Rails 7.1, consulte las notas de lanzamiento.
3.1 Archivo secret_key_base cambiado en entornos de desarrollo y prueba
En los entornos de desarrollo y prueba, el archivo del que Rails lee el secret_key_base
se ha renombrado de tmp/development_secret.txt
a tmp/local_secret.txt
.
Simplemente puede renombrar el archivo anterior a local_secret.txt
para continuar usando el mismo secreto, o copiar la clave del archivo anterior al nuevo.
No hacerlo causará que Rails genere una nueva clave secreta en el nuevo archivo tmp/local_secret.txt
cuando se cargue la aplicación.
Esto invalidará todas las sesiones/cookies existentes en los entornos de desarrollo y prueba, y también causará que otras firmas derivadas de secret_key_base
se rompan, como los archivos adjuntos de Active Storage/Action Text.
La producción y otros entornos no se ven afectados.
3.2 Las rutas autoloaded ya no están en $LOAD_PATH
A partir de Rails 7.1, los directorios gestionados por los autoloaders ya no se agregan a $LOAD_PATH
. Esto significa que no será posible cargar sus archivos con una llamada manual a require
, lo cual no debería hacerse de todos modos.
Reducir el tamaño de $LOAD_PATH
acelera las llamadas a require
para aplicaciones que no usan bootsnap
, y reduce el tamaño del caché de bootsnap
para las demás.
Si desea que estas rutas todavía estén en $LOAD_PATH
, puede optar por incluirlas:
config.add_autoload_paths_to_load_path = true
pero desaconsejamos hacerlo, las clases y módulos en las rutas de carga automática están destinadas a ser cargadas automáticamente. Es decir, simplemente refiérase a ellas.
El directorio lib
no se ve afectado por este indicador, siempre se agrega a $LOAD_PATH
.
3.3 config.autoload_lib y config.autoload_lib_once
Si su aplicación no tiene lib
en las rutas de carga automática o de carga automática única, por favor omita esta sección. Puede averiguarlo inspeccionando la salida de
# Imprimir rutas de carga automática.
$ bin/rails runner 'pp Rails.autoloaders.main.dirs'
# Imprimir rutas de carga automática única.
$ bin/rails runner 'pp Rails.autoloaders.once.dirs'
Si su aplicación ya tiene lib
en las rutas de carga automática, normalmente hay una configuración en config/application.rb
que se ve algo así
# Cargar automáticamente lib, pero no cargarla ansiosamente (quizás pasado por alto).
config.autoload_paths << config.root.join("lib")
o
# Cargar automáticamente y también cargar ansiosamente lib.
config.autoload_paths << config.root.join("lib")
config.eager_load_paths << config.root.join("lib")
o
# Lo mismo, porque todas las rutas de carga ansiosa también se convierten en rutas de carga automática.
config.eager_load_paths << config.root.join("lib")
Eso todavía funciona, pero se recomienda reemplazar esas líneas con el más conciso
config.autoload_lib(ignore: %w(assets tasks))
Por favor, agregue a la lista de ignore
cualquier otro subdirectorio de lib
que no contenga archivos .rb
, o que no deba ser recargado o cargado ansiosamente. Por ejemplo, si su aplicación tiene lib/templates
, lib/generators
o lib/middleware
, agregaría su nombre relativo a lib
:
config.autoload_lib(ignore: %w(assets tasks templates generators middleware))
Con esa línea, el código (no ignorado) en lib
también se cargará ansiosamente si config.eager_load
es true
(el valor predeterminado en modo production
). Esto es normalmente lo que desea, pero si lib
no se agregó a las rutas de carga ansiosa antes y aún lo desea de esa manera, por favor opte por no hacerlo:
Rails.autoloaders.main.do_not_eager_load(config.root.join("lib"))
El método config.autoload_lib_once
es el análogo si la aplicación tenía lib
en config.autoload_once_paths
.
3.4 ActiveStorage::BaseController
ya no incluye el concern de streaming
Los controladores de aplicaciones que heredan de ActiveStorage::BaseController
y usan streaming para implementar lógica de servicio de archivos personalizada deben incluir explícitamente el módulo ActiveStorage::Streaming
.
3.5 MemCacheStore
y RedisCacheStore
ahora usan agrupación de conexiones por defecto
El gem connection_pool
se ha agregado como una dependencia del gem activesupport
, y MemCacheStore
y RedisCacheStore
ahora usan agrupación de conexiones por defecto.
Si no desea usar agrupación de conexiones, configure la opción :pool
en false
al configurar su almacén de caché:
config.cache_store = :mem_cache_store, "cache.example.com", { pool: false }
Consulte la guía caching with Rails para obtener más información.
3.6 SQLite3Adapter
ahora configurado para usarse en un modo estricto de cadenas
El uso de un modo estricto de cadenas deshabilita los literales de cadena entre comillas dobles.
SQLite tiene algunas peculiaridades en torno a los literales de cadena entre comillas dobles. Primero intenta considerar las cadenas entre comillas dobles como nombres de identificadores, pero si no existen, entonces las considera como literales de cadena. Debido a esto, los errores tipográficos pueden pasar desapercibidos. Por ejemplo, es posible crear un índice para una columna no existente. Consulte la documentación de SQLite para obtener más detalles.
Si no desea usar SQLite3Adapter
en un modo estricto, puede deshabilitar este comportamiento:
# config/application.rb
config.active_record.sqlite3_adapter_strict_strings_by_default = false
3.7 Soporte para múltiples rutas de vista previa para ActionMailer::Preview
La opción config.action_mailer.preview_path
está obsoleta en favor de config.action_mailer.preview_paths
. Agregar rutas a esta opción de configuración hará que esas rutas se utilicen en la búsqueda de vistas previas de correo.
config.action_mailer.preview_paths << "#{Rails.root}/lib/mailer_previews"
3.8 config.i18n.raise_on_missing_translations = true
ahora genera un error en cualquier traducción faltante.
Anteriormente, solo generaba un error cuando se llamaba en una vista o controlador. Ahora generará un error cada vez que I18n.t
reciba una clave no reconocida.
# con config.i18n.raise_on_missing_translations = true
# en una vista o controlador:
t("missing.key") # genera un error en 7.0, genera un error en 7.1
I18n.t("missing.key") # no generaba un error en 7.0, genera un error en 7.1
# en cualquier lugar:
I18n.t("missing.key") # no generaba un error en 7.0, genera un error en 7.1
Si no desea este comportamiento, puede configurar config.i18n.raise_on_missing_translations = false
:
# con config.i18n.raise_on_missing_translations = false
# en una vista o controlador:
t("missing.key") # no generaba un error en 7.0, no genera un error en 7.1
I18n.t("missing.key") # no generaba un error en 7.0, no genera un error en 7.1
# en cualquier lugar:
I18n.t("missing.key") # no generaba un error en 7.0, no genera un error en 7.1
Alternativamente, puede personalizar el I18n.exception_handler
. Consulte la guía i18n para obtener más información.
AbstractController::Translation.raise_on_missing_translations
ha sido eliminado. Esta era una API privada, si dependía de ella, debería migrar a config.i18n.raise_on_missing_translations
o a un manejador de excepciones personalizado.
3.9 bin/rails test
ahora ejecuta la tarea test:prepare
Al ejecutar pruebas a través de bin/rails test
, la tarea rake test:prepare
se ejecutará antes de que se ejecuten las pruebas. Si ha mejorado la tarea test:prepare
, sus mejoras se ejecutarán antes de sus pruebas. tailwindcss-rails
, jsbundling-rails
y cssbundling-rails
mejoran esta tarea, al igual que otros gems de terceros.
Consulte la guía Testing Rails Applications para obtener más información.
Si ejecuta las pruebas de un solo archivo (bin/rails test test/models/user_test.rb
), test:prepare
no se ejecutará antes de ellas.
3.10 La sintaxis de importación de @rails/ujs
se ha modificado
A partir de Rails 7.1, la sintaxis para importar módulos de @rails/ujs
se ha modificado. Rails ya no admite la importación directa de un módulo desde @rails/ujs
.
Por ejemplo, intentar importar una función de la biblioteca fallará:
import { fileInputSelector } from "@rails/ujs"
// ERROR: export 'fileInputSelector' (importado como 'fileInputSelector') no se encontró en '@rails/ujs' (posibles exportaciones: default)
En Rails 7.1, los usuarios deben importar primero el objeto Rails directamente desde @rails/ujs
. Luego, los usuarios pueden importar módulos específicos desde el objeto Rails.
Un ejemplo de importaciones en Rails 7.1 se muestra a continuación:
import Rails from "@rails/ujs"
// Alias del método
const fileInputSelector = Rails.fileInputSelector
// Alternativamente, referenciarlo desde el objeto Rails donde se utiliza
Rails.fileInputSelector(...)
3.11 Rails.logger
ahora devuelve una instancia de ActiveSupport::BroadcastLogger
La clase ActiveSupport::BroadcastLogger
es un nuevo logger que permite transmitir registros a diferentes destinos (STDOUT, un archivo de registro...) de manera sencilla.
La API para transmitir registros (usando el método ActiveSupport::Logger.broadcast
) fue eliminada y anteriormente era privada. Si su aplicación o biblioteca dependía de esta API, necesita realizar los siguientes cambios:
logger = Logger.new("some_file.log")
# Antes
Rails.logger.extend(ActiveSupport::Logger.broadcast(logger))
# Después
Rails.logger.broadcast_to(logger)
Si su aplicación había configurado un logger personalizado, Rails.logger
envolverá y hará proxy de todos los métodos a él. No se requieren cambios de su parte para que funcione.
Si necesita acceder a su instancia de logger personalizada, puede hacerlo utilizando el método broadcasts
:
# config/application.rb
config.logger = MyLogger.new
# En cualquier lugar de su aplicación
puts Rails.logger.class #=> BroadcastLogger
puts Rails.logger.broadcasts #=> [MyLogger]
3.12 Cambios en el algoritmo de cifrado de Active Record
El cifrado de Active Record ahora utiliza SHA-256 como su algoritmo de hash digest. Si tiene datos cifrados con versiones anteriores de Rails, hay dos escenarios a considerar:
Si tiene
config.active_support.key_generator_hash_digest_class
configurado como SHA-1 (el valor predeterminado antes de Rails 7.0), necesita configurar SHA-1 para el cifrado de Active Record también:config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1
Si tiene
config.active_support.key_generator_hash_digest_class
configurado como SHA-256 (el nuevo valor predeterminado en 7.0), entonces necesita configurar SHA-256 para el cifrado de Active Record:config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256
Consulte la guía Configuring Rails Applications para obtener más información sobre config.active_record.encryption.hash_digest_class
.
Además, se introdujo una nueva configuración config.active_record.encryption.support_sha1_for_non_deterministic_encryption
para resolver un error que causaba que algunos atributos se cifraran usando SHA-1 incluso cuando SHA-256 estaba configurado a través de la configuración mencionada anteriormente hash_digest_class
.
Por defecto, config.active_record.encryption.support_sha1_for_non_deterministic_encryption
está deshabilitado en Rails 7.1. Si tiene datos cifrados en una versión de Rails < 7.1 que cree que puede estar afectada por el error mencionado anteriormente, esta configuración debe habilitarse:
config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
Si está trabajando con datos cifrados, revise cuidadosamente lo anterior.
3.13 Nuevas formas de manejar excepciones en Pruebas de Controladores, Pruebas de Integración y Pruebas de Sistema
La configuración config.action_dispatch.show_exceptions
controla cómo Action Pack maneja las excepciones generadas mientras responde a solicitudes.
Antes de Rails 7.1, configurar config.action_dispatch.show_exceptions = true
configuraba Action Pack para rescatar excepciones y renderizar páginas de error HTML apropiadas, como renderizar public/404.html
con un código de estado 404 Not found
en lugar de generar una excepción ActiveRecord::RecordNotFound
. Configurar config.action_dispatch.show_exceptions = false
configuraba Action Pack para no rescatar la excepción. Antes de Rails 7.1, las nuevas aplicaciones se generaban con una línea en config/environments/test.rb
que configuraba config.action_dispatch.show_exceptions = false
.
Rails 7.1 cambia los valores aceptables de true
y false
a :all
, :rescuable
y :none
.
:all
- renderizar páginas de error HTML para todas las excepciones (equivalente atrue
):rescuable
- renderizar páginas de error HTML para excepciones declaradas porconfig.action_dispatch.rescue_responses
:none
(equivalente afalse
) - no rescatar ninguna excepción
Las aplicaciones generadas por Rails 7.1 o posteriores configuran config.action_dispatch.show_exceptions = :rescuable
en su config/environments/test.rb
. Al actualizar, las aplicaciones existentes pueden cambiar config.action_dispatch.show_exceptions = :rescuable
para utilizar el nuevo comportamiento, o reemplazar los valores antiguos con los nuevos correspondientes (true
reemplaza :all
, false
reemplaza :none
).
4 Actualización de Rails 6.1 a Rails 7.0
Para obtener más información sobre los cambios realizados en Rails 7.0, consulte las notas de lanzamiento.
4.1 Cambió el comportamiento de ActionView::Helpers::UrlHelper#button_to
A partir de Rails 7.0, button_to
renderiza una etiqueta form
con el verbo HTTP patch
si se utiliza un objeto Active Record persistente para construir la URL del botón. Para mantener el comportamiento actual, considere pasar explícitamente la opción method:
:
-button_to("Do a POST", [:my_custom_post_action_on_workshop, Workshop.find(1)])
+button_to("Do a POST", [:my_custom_post_action_on_workshop, Workshop.find(1)], method: :post)
o usar un helper para construir la URL:
-button_to("Do a POST", [:my_custom_post_action_on_workshop, Workshop.find(1)])
+button_to("Do a POST", my_custom_post_action_on_workshop_workshop_path(Workshop.find(1)))
4.2 Spring
Si su aplicación usa Spring, necesita actualizarlo al menos a la versión 3.0.0. De lo contrario, recibirá
undefined method `mechanism=' for ActiveSupport::Dependencies:Module
Además, asegúrese de que config.cache_classes
esté configurado en false
en config/environments/test.rb
.
4.3 Sprockets ahora es una dependencia opcional
El gem rails
ya no depende de sprockets-rails
. Si su aplicación aún necesita usar Sprockets, asegúrese de agregar sprockets-rails
a su Gemfile.
gem "sprockets-rails"
4.4 Las aplicaciones deben ejecutarse en modo zeitwerk
Las aplicaciones que aún se ejecutan en modo classic
deben cambiar a modo zeitwerk
. Consulte la guía Classic to Zeitwerk HOWTO para obtener detalles.
4.5 El setter config.autoloader=
ha sido eliminado
En Rails 7 no hay un punto de configuración para establecer el modo de carga automática, config.autoloader=
ha sido eliminado. Si lo tenía configurado como :zeitwerk
por cualquier razón, simplemente elimínelo.
4.6 La API privada de ActiveSupport::Dependencies
ha sido eliminada
La API privada de ActiveSupport::Dependencies
ha sido eliminada. Esto incluye métodos como hook!
, unhook!
, depend_on
, require_or_load
, mechanism
y muchos otros.
Algunos de los aspectos destacados:
- Si usaba
ActiveSupport::Dependencies.constantize
oActiveSupport::Dependencies.safe_constantize
, simplemente cámbielos porString#constantize
oString#safe_constantize
.
ActiveSupport::Dependencies.constantize("User") # YA NO ES POSIBLE
"User".constantize # 👍
Cualquier uso de
ActiveSupport::Dependencies.mechanism
, lector o escritor, debe ser reemplazado accediendo aconfig.cache_classes
en consecuencia.Si desea rastrear la actividad del cargador automático,
ActiveSupport::Dependencies.verbose=
ya no está disponible, simplemente arrojeRails.autoloaders.log!
enconfig/application.rb
.
Las clases o módulos internos auxiliares también se han ido, como ActiveSupport::Dependencies::Reference
, ActiveSupport::Dependencies::Blamable
y otros.
4.7 Carga automática durante la inicialización
Las aplicaciones que cargaron automáticamente constantes recargables durante la inicialización fuera de los bloques de to_prepare
obtuvieron esas constantes descargadas y se emitió esta advertencia desde Rails 6.0:
DEPRECATION WARNING: Initialization autoloaded the constant ....
Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.
...
Si aún recibe esta advertencia en los registros, consulte la sección sobre carga automática cuando la aplicación se inicia en la guía de carga automática. De lo contrario, obtendría un NameError
en Rails 7.
Las constantes gestionadas por el cargador automático once
pueden ser cargadas automáticamente durante la inicialización y pueden ser usadas normalmente, no es necesario un bloque to_prepare
. Sin embargo, el cargador automático once
ahora se configura antes para soportar eso. Si la aplicación tiene inflexiones personalizadas y el cargador automático once
debe ser consciente de ellas, necesita mover el código en config/initializers/inflections.rb
al cuerpo de la definición de la clase de la aplicación en config/application.rb
:
module MyApp
class Application < Rails::Application
# ...
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym "HTML"
end
end
end
4.8 Capacidad de configurar config.autoload_once_paths
config.autoload_once_paths
se puede configurar en el cuerpo de la clase de la aplicación definida en config/application.rb
o en la configuración para entornos en config/environments/*
.
De manera similar, los motores pueden configurar esa colección en el cuerpo de la clase del motor o en la configuración para entornos.
Después de eso, la colección se congela y puede cargar automáticamente desde esas rutas. En particular, puede cargar automáticamente desde allí durante la inicialización. Son gestionadas por el cargador automático Rails.autoloaders.once
, que no recarga, solo carga automáticamente/carga ansiosamente.
Si configuró esta configuración después de que se haya procesado la configuración de los entornos y está obteniendo FrozenError
, simplemente mueva el código.
4.9 ActionDispatch::Request#content_type
ahora devuelve el encabezado Content-Type tal como es.
Anteriormente, el valor devuelto de ActionDispatch::Request#content_type
NO contenía la parte de charset. Este comportamiento cambió para devolver el encabezado Content-Type que contiene la parte de charset tal como es.
Si solo desea el tipo MIME, use ActionDispatch::Request#media_type
en su lugar.
Antes:
request = ActionDispatch::Request.new("CONTENT_TYPE" => "text/csv; header=present; charset=utf-16", "REQUEST_METHOD" => "GET")
request.content_type #=> "text/csv"
Después:
request = ActionDispatch::Request.new("Content-Type" => "text/csv; header=present; charset=utf-16", "REQUEST_METHOD" => "GET")
request.content_type #=> "text/csv; header=present; charset=utf-16"
request.media_type #=> "text/csv"
4.10 El cambio de clase digest del generador de claves requiere un rotador de cookies
La clase digest predeterminada para el generador de claves está cambiando de SHA1 a SHA256. Esto tiene consecuencias en cualquier mensaje cifrado generado por Rails, incluidas las cookies cifradas.
Para poder leer mensajes usando la clase digest antigua, es necesario registrar un rotador. No hacerlo puede resultar en que los usuarios tengan sus sesiones invalidadas durante la actualización.
El siguiente es un ejemplo de rotador para las cookies cifradas y firmadas.
# config/initializers/cookie_rotator.rb
Rails.application.config.after_initialize do
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
authenticated_encrypted_cookie_salt = Rails.application.config.action_dispatch.authenticated_encrypted_cookie_salt
signed_cookie_salt = Rails.application.config.action_dispatch.signed_cookie_salt
secret_key_base = Rails.application.secret_key_base
key_generator = ActiveSupport::KeyGenerator.new(
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1
)
key_len = ActiveSupport::MessageEncryptor.key_len
old_encrypted_secret = key_generator.generate_key(authenticated_encrypted_cookie_salt, key_len)
old_signed_secret = key_generator.generate_key(signed_cookie_salt)
cookies.rotate :encrypted, old_encrypted_secret
cookies.rotate :signed, old_signed_secret
end
end
4.11 Cambio de clase digest para ActiveSupport::Digest a SHA256
La clase digest predeterminada para ActiveSupport::Digest está cambiando de SHA1 a SHA256. Esto tiene consecuencias para cosas como los Etags que cambiarán y las claves de caché también. Cambiar estas claves puede tener un impacto en las tasas de aciertos de caché, así que tenga cuidado y esté atento a esto al actualizar al nuevo hash.
4.12 Nuevo formato de serialización de caché en ActiveSupport
Se introdujo un formato de serialización más rápido y compacto.
Para habilitarlo, debe establecer config.active_support.cache_format_version = 7.0
:
# config/application.rb
config.load_defaults 6.1
config.active_support.cache_format_version = 7.0
O simplemente:
# config/application.rb
config.load_defaults 7.0
Sin embargo, las aplicaciones de Rails 6.1 no pueden leer este nuevo formato de serialización, por lo que para garantizar una actualización sin problemas, primero debe implementar su actualización de Rails 7.0 con config.active_support.cache_format_version = 6.1
, y luego, solo una vez que todos los procesos de Rails se hayan actualizado, puede establecer config.active_support.cache_format_version = 7.0
.
Rails 7.0 puede leer ambos formatos, por lo que la caché no se invalidará durante la actualización.
4.13 Generación de imágenes de vista previa de video en Active Storage
La generación de imágenes de vista previa de video ahora utiliza la detección de cambios de escena de FFmpeg para generar imágenes de vista previa más significativas. Anteriormente, se utilizaba el primer fotograma del video y eso causaba problemas si el video se desvanecía de negro. Este cambio requiere FFmpeg v3.4+.
4.14 Procesador de variantes predeterminado de Active Storage cambiado a :vips
Para nuevas aplicaciones, la transformación de imágenes usará libvips en lugar de ImageMagick. Esto reducirá el tiempo necesario para generar variantes, así como el uso de CPU y memoria, mejorando los tiempos de respuesta en aplicaciones que dependen de Active Storage para servir sus imágenes.
La opción :mini_magick
no está siendo desaprobada, por lo que está bien seguir usándola.
Para migrar una aplicación existente a libvips, configure:
Rails.application.config.active_storage.variant_processor = :vips
Luego deberá cambiar el código de transformación de imágenes existente a los macros de image_processing
y reemplazar las opciones de ImageMagick con las opciones de libvips.
4.14.1 Reemplace resize con resize_to_limit
- variant(resize: "100x")
+ variant(resize_to_limit: [100, nil])
Si no hace esto, cuando cambie a vips verá este error: no implicit conversion to float from string
.
4.14.2 Use una matriz al recortar
- variant(crop: "1920x1080+0+0")
+ variant(crop: [0, 0, 1920, 1080])
Si no hace esto al migrar a vips, verá el siguiente error: unable to call crop: you supplied 2 arguments, but operation needs 5
.
4.14.3 Ajuste los valores de recorte:
Vips es más estricto que ImageMagick cuando se trata de recortar:
- No recortará si
x
y/oy
son valores negativos. por ejemplo:[-10, -10, 100, 100]
- No recortará si la posición (
x
oy
) más la dimensión de recorte (width
,height
) es mayor que la imagen. por ejemplo: una imagen de 125x125 y un recorte de[50, 50, 100, 100]
Si no hace esto al migrar a vips, verá el siguiente error: extract_area: bad extract area
4.14.4 Ajuste el color de fondo utilizado para resize_and_pad
Vips usa negro como el color de fondo predeterminado para resize_and_pad
, en lugar de blanco como ImageMagick. Solucione eso usando la opción background
:
- variant(resize_and_pad: [300, 300])
+ variant(resize_and_pad: [300, 300, background: [255]])
4.14.5 Elimine cualquier rotación basada en EXIF
Vips rotará automáticamente las imágenes usando el valor EXIF al procesar variantes. Si estaba almacenando valores de rotación de fotos cargadas por el usuario para aplicar la rotación con ImageMagick, debe dejar de hacerlo:
- variant(format: :jpg, rotate: rotation_value)
+ variant(format: :jpg)
4.14.6 Reemplace monochrome con colourspace
Vips usa una opción diferente para hacer imágenes monocromáticas:
- variant(monochrome: true)
+ variant(colourspace: "b-w")
4.14.7 Cambie a opciones de libvips para comprimir imágenes
JPEG
- variant(strip: true, quality: 80, interlace: "JPEG", sampling_factor: "4:2:0", colorspace: "sRGB")
+ variant(saver: { strip: true, quality: 80, interlace: true })
PNG
- variant(strip: true, quality: 75)
+ variant(saver: { strip: true, compression: 9 })
WEBP
- variant(strip: true, quality: 75, define: { webp: { lossless: false, alpha_quality: 85, thread_level: 1 } })
+ variant(saver: { strip: true, quality: 75, lossless: false, alpha_q: 85, reduction_effort: 6, smart_subsample: true })
GIF
- variant(layers: "Optimize")
+ variant(saver: { optimize_gif_frames: true, optimize_gif_transparency: true })
4.14.8 Despliegue a producción
Active Storage codifica en la URL de la imagen la lista de transformaciones que deben realizarse. Si su aplicación está almacenando en caché estas URL, sus imágenes se romperán después de implementar el nuevo código en producción. Debido a esto, debe invalidar manualmente sus claves de caché afectadas.
Por ejemplo, si tiene algo como esto en una vista:
<% @products.each do |product| %>
<% cache product do %>
<%= image_tag product.cover_photo.variant(resize: "200x") %>
<% end %>
<% end %>
Puede invalidar la caché tocando el producto o cambiando la clave de caché:
<% @products.each do |product| %>
<% cache ["v2", product] do %>
<%= image_tag product.cover_photo.variant(resize_to_limit: [200, nil]) %>
<% end %>
<% end %>
4.15 La versión de Rails ahora se incluye en el volcado de esquema de Active Record
Rails 7.0 cambió algunos valores predeterminados para algunos tipos de columnas. Para evitar que las aplicaciones que se actualizan de 6.1 a 7.0 carguen el esquema actual usando los nuevos valores predeterminados de 7.0, Rails ahora incluye la versión del framework en el volcado de esquema.
Antes de cargar el esquema por primera vez en Rails 7.0, asegúrese de ejecutar rails app:update
para garantizar que la versión del esquema se incluya en el volcado de esquema.
El archivo de esquema se verá así:
# Este archivo se genera automáticamente a partir del estado actual de la base de datos. En lugar
# de editar este archivo, utilice la función de migraciones de Active Record para
# modificar su base de datos de manera incremental y luego regenere esta definición de esquema.
#
# Este archivo es la fuente que Rails utiliza para definir su esquema al ejecutar `bin/rails
# db:schema:load`. Al crear una nueva base de datos, `bin/rails db:schema:load` tiende a
# ser más rápido y es potencialmente menos propenso a errores que ejecutar todas sus
# migraciones desde cero. Las migraciones antiguas pueden fallar al aplicarse correctamente si esas
# migraciones utilizan dependencias externas o código de aplicación.
#
# Se recomienda encarecidamente que registre este archivo en su sistema de control de versiones.
ActiveRecord::Schema[6.1].define(version: 2022_01_28_123512) do
# ...
end
NOTA: La primera vez que realice un volcado del esquema con Rails 7.0, verá muchos cambios en ese archivo, incluida información de algunas columnas. Asegúrese de revisar el nuevo contenido del archivo de esquema y comprometerlo en su repositorio.
5 Actualización de Rails 6.0 a Rails 6.1
Para obtener más información sobre los cambios realizados en Rails 6.1, consulte las notas de lanzamiento.
5.1 El valor de retorno de Rails.application.config_for
ya no admite el acceso con claves de cadena.
Dado un archivo de configuración como este:
# config/example.yml
development:
options:
key: value
Rails.application.config_for(:example).options
Esto solía devolver un hash en el que podía acceder a los valores con claves de cadena. Eso estaba desaprobado en 6.0 y ahora ya no funciona.
Puede llamar a with_indifferent_access
en el valor de retorno de config_for
si aún desea acceder a los valores con claves de cadena, por ejemplo:
Rails.application.config_for(:example).with_indifferent_access.dig('options', 'key')
5.2 Tipo de contenido de la respuesta al usar respond_to#any
El encabezado Content-Type devuelto en la respuesta puede diferir de lo que Rails 6.0 devolvía, más específicamente si su aplicación usa respond_to { |format| format.any }
. El Content-Type ahora se basará en el bloque dado en lugar del formato de la solicitud.
Ejemplo:
def my_action
respond_to do |format|
format.any { render(json: { foo: 'bar' }) }
end
end
get('my_action.csv')
El comportamiento anterior devolvía un Content-Type de respuesta text/csv
, lo cual es inexacto ya que se está renderizando una respuesta JSON. El comportamiento actual devuelve correctamente un Content-Type de respuesta application/json
.
Si su aplicación depende del comportamiento incorrecto anterior, se le recomienda especificar qué formatos acepta su acción, es decir:
format.any(:xml, :json) { render request.format.to_sym => @people }
5.3 ActiveSupport::Callbacks#halted_callback_hook
ahora recibe un segundo argumento
Active Support permite anular el halted_callback_hook
cuando una devolución de llamada detiene la cadena. Este método ahora recibe un segundo argumento que es el nombre de la devolución de llamada que se detiene. Si tiene clases que anulan este método, asegúrese de que acepte dos argumentos. Tenga en cuenta que este es un cambio que rompe la compatibilidad sin un ciclo de desaprobación previo (por razones de rendimiento).
Ejemplo:
class Book < ApplicationRecord
before_save { throw(:abort) }
before_create { throw(:abort) }
def halted_callback_hook(filter, callback_name) # => Este método ahora acepta 2 argumentos en lugar de 1
Rails.logger.info("Book couldn't be #{callback_name}d")
end
end
5.4 El método de clase helper
en controladores usa String#constantize
Conceptualmente, antes de Rails 6.1
helper "foo/bar"
resultaba en
require_dependency "foo/bar_helper"
module_name = "foo/bar_helper".camelize
module_name.constantize
Ahora hace esto en su lugar:
prefix = "foo/bar".camelize
"#{prefix}Helper".constantize
Este cambio es compatible con versiones anteriores para la mayoría de las aplicaciones, en cuyo caso no necesita hacer nada.
Técnicamente, sin embargo, los controladores podrían configurar helpers_path
para apuntar a un directorio en $LOAD_PATH
que no estaba en las rutas de carga automática. Ese caso de uso ya no es compatible de forma predeterminada. Si el módulo de ayuda no se puede cargar automáticamente, la aplicación es responsable de cargarlo antes de llamar a helper
.
5.5 La redirección a HTTPS desde HTTP ahora usará el código de estado HTTP 308
El código de estado HTTP predeterminado utilizado en ActionDispatch::SSL
al redirigir solicitudes no GET/HEAD de HTTP a HTTPS ha cambiado a 308
como se define en https://tools.ietf.org/html/rfc7538.
5.6 Active Storage ahora requiere Image Processing
Al procesar variantes en Active Storage, ahora es necesario tener el gem image_processing incluido en lugar de usar directamente mini_magick
. Image Processing está configurado de manera predeterminada para usar mini_magick
detrás de escena, por lo que la forma más fácil de actualizar es reemplazar el gem mini_magick
por el gem image_processing
y asegurarse de eliminar el uso explícito de combine_options
ya que ya no es necesario.
Para mayor legibilidad, puede desear cambiar las llamadas resize
sin procesar a macros de image_processing
. Por ejemplo, en lugar de:
video.preview(resize: "100x100")
video.preview(resize: "100x100>")
video.preview(resize: "100x100^")
puede hacer respectivamente:
video.preview(resize_to_fit: [100, 100])
video.preview(resize_to_limit: [100, 100])
video.preview(resize_to_fill: [100, 100])
5.7 Nueva clase ActiveModel::Error
Los errores ahora son instancias de una nueva clase ActiveModel::Error
, con cambios en la API. Algunos de estos cambios pueden generar errores dependiendo de cómo manipule los errores, mientras que otros imprimirán advertencias de desaprobación para ser corregidos en Rails 7.0.
Puede encontrar más información sobre este cambio y detalles sobre los cambios en la API en este PR.
6 Actualización de Rails 5.2 a Rails 6.0
Para obtener más información sobre los cambios realizados en Rails 6.0, consulte las notas de lanzamiento.
6.1 Uso de Webpacker
Webpacker es el compilador de JavaScript predeterminado para Rails 6. Pero si está actualizando la aplicación, no se activa de manera predeterminada. Si desea usar Webpacker, inclúyalo en su Gemfile e instálelo:
gem "webpacker"
$ bin/rails webpacker:install
6.2 Forzar SSL
El método force_ssl
en los controladores ha sido desaprobado y se eliminará en Rails 6.1. Se le recomienda habilitar config.force_ssl
para forzar conexiones HTTPS en toda su aplicación. Si necesita eximir ciertos puntos finales de la redirección, puede usar config.ssl_options
para configurar ese comportamiento.
6.3 El propósito y la expiración de los metadatos ahora están incrustados dentro de las cookies firmadas y cifradas para aumentar la seguridad
Para mejorar la seguridad, Rails incrusta el propósito y la expiración de los metadatos dentro del valor de las cookies cifradas o firmadas.
Rails puede frustrar los ataques que intentan copiar el valor firmado/cifrado de una cookie y usarlo como el valor de otra cookie.
Esta nueva incrustación de metadatos hace que esas cookies sean incompatibles con versiones de Rails anteriores a 6.0.
Si necesita que sus cookies sean leídas por Rails 5.2 y versiones anteriores, o aún está validando su implementación de 6.0 y desea poder revertir, establezca Rails.application.config.action_dispatch.use_cookies_with_metadata
en false
.
6.4 Todos los paquetes npm se han movido al alcance @rails
Si anteriormente estaba cargando alguno de los paquetes actioncable
, activestorage
o rails-ujs
a través de npm/yarn, debe actualizar los nombres de estas dependencias antes de poder actualizarlas a 6.0.0
:
actioncable → @rails/actioncable
activestorage → @rails/activestorage
rails-ujs → @rails/ujs
6.5 Cambios en la API de JavaScript de Action Cable
El paquete de JavaScript de Action Cable se ha convertido de CoffeeScript a ES2015, y ahora publicamos el código fuente en la distribución npm.
Esta versión incluye algunos cambios importantes en las partes opcionales de la API de JavaScript de Action Cable:
La configuración del adaptador WebSocket y del adaptador logger se ha movido de propiedades de
ActionCable
a propiedades deActionCable.adapters
. Si está configurando estos adaptadores, deberá realizar estos cambios:- ActionCable.WebSocket = MyWebSocket + ActionCable.adapters.WebSocket = MyWebSocket
- ActionCable.logger = myLogger + ActionCable.adapters.logger = myLogger
Los métodos
ActionCable.startDebugging()
yActionCable.stopDebugging()
se han eliminado y se han reemplazado con la propiedadActionCable.logger.enabled
. Si está utilizando estos métodos, deberá realizar estos cambios:- ActionCable.startDebugging() + ActionCable.logger.enabled = true
- ActionCable.stopDebugging() + ActionCable.logger.enabled = false
6.6 ActionDispatch::Response#content_type
ahora devuelve el encabezado Content-Type sin modificación
Anteriormente, el valor devuelto de ActionDispatch::Response#content_type
NO contenía la parte de charset. Este comportamiento ha cambiado para incluir la parte de charset previamente omitida también.
Si solo desea el tipo MIME, use ActionDispatch::Response#media_type
en su lugar.
Antes:
resp = ActionDispatch::Response.new(200, "Content-Type" => "text/csv; header=present; charset=utf-16")
resp.content_type #=> "text/csv; header=present"
Después:
resp = ActionDispatch::Response.new(200, "Content-Type" => "text/csv; header=present; charset=utf-16")
resp.content_type #=> "text/csv; header=present; charset=utf-16"
resp.media_type #=> "text/csv"
6.7 Nueva configuración config.hosts
Rails ahora tiene una nueva configuración config.hosts
por razones de seguridad. Esta configuración predetermina localhost
en desarrollo. Si usa otros dominios en desarrollo, necesita permitirlos así:
# config/environments/development.rb
config.hosts << 'dev.myapp.com'
config.hosts << /[a-z0-9-]+\.myapp\.com/ # Opcionalmente, también se permite una expresión regular
Para otros entornos, config.hosts
está vacío por defecto, lo que significa que Rails no validará el host en absoluto. Puede agregarlos opcionalmente si desea validarlo en producción.
6.8 Carga automática
La configuración predeterminada para Rails 6
# config/application.rb
config.load_defaults 6.0
habilita el modo de carga automática zeitwerk
en CRuby. En ese modo, la carga automática, la recarga y la carga ansiosa son gestionadas por Zeitwerk.
Si está utilizando los valores predeterminados de una versión anterior de Rails, puede habilitar zeitwerk así:
# config/application.rb
config.autoloader = :zeitwerk
6.8.1 API Pública
En general, las aplicaciones no necesitan usar la API de Zeitwerk directamente. Rails configura las cosas de acuerdo con el contrato existente: config.autoload_paths
, config.cache_classes
, etc.
Aunque las aplicaciones deben ceñirse a esa interfaz, el objeto del cargador automático Zeitwerk real se puede acceder como
Rails.autoloaders.main
Eso puede ser útil si necesita precargar clases de Herencia de Tabla Única (STI) o configurar un inflector personalizado, por ejemplo.
6.8.2 Estructura del Proyecto
Si la aplicación que se está actualizando carga automáticamente correctamente, la estructura del proyecto debería ser ya mayormente compatible.
Sin embargo, el modo classic
infiere nombres de archivos a partir de nombres de constantes faltantes (underscore
), mientras que el modo zeitwerk
infiere nombres de constantes a partir de nombres de archivos (camelize
). Estos ayudantes no siempre son inversos entre sí, en particular si están involucrados acrónimos. Por ejemplo, "FOO".underscore
es "foo"
, pero "foo".camelize
es "Foo"
, no "FOO"
.
La compatibilidad se puede verificar con la tarea zeitwerk:check
:
$ bin/rails zeitwerk:check
Hold on, I am eager loading the application.
All is good!
6.8.3 require_dependency
Todos los casos de uso conocidos de require_dependency
han sido eliminados, debe buscar en el proyecto y eliminarlos.
Si su aplicación utiliza Herencia de Tabla Única, consulte la sección de Herencia de Tabla Única de la guía de Carga Automática y Recarga de Constantes (Modo Zeitwerk).
6.8.4 Nombres calificados en definiciones de clases y módulos
Ahora puede usar de manera robusta rutas constantes en definiciones de clases y módulos:
# La carga automática en el cuerpo de esta clase ahora coincide con la semántica de Ruby.
class Admin::UsersController < ApplicationController
# ...
end
Un inconveniente a tener en cuenta es que, dependiendo del orden de ejecución, el cargador automático clásico a veces podría ser capaz de cargar automáticamente Foo::Wadus
en
class Foo::Bar
Wadus
end
Eso no coincide con la semántica de Ruby porque Foo
no está en el anidamiento, y no funcionará en absoluto en el modo zeitwerk
. Si encuentra tal caso, puede usar el nombre calificado Foo::Wadus
:
class Foo::Bar
Foo::Wadus
end
o agregar Foo
al anidamiento:
module Foo
class Bar
Wadus
end
end
6.8.5 Concerns
Puede cargar automáticamente y cargar ansiosamente desde una estructura estándar como
app/models
app/models/concerns
En ese caso, se asume que app/models/concerns
es un directorio raíz (porque pertenece a las rutas de carga automática) y se ignora como espacio de nombres. Entonces, app/models/concerns/foo.rb
debería definir Foo
, no Concerns::Foo
.
El espacio de nombres Concerns::
funcionó con el cargador automático clásico como un efecto secundario de la implementación, pero realmente no era un comportamiento intencionado. Una aplicación que usa Concerns::
necesita renombrar esas clases y módulos para poder ejecutarse en modo zeitwerk
.
6.8.6 Tener app
en las rutas de carga automática
Algunos proyectos quieren algo como app/api/base.rb
para definir API::Base
, y agregan app
a las rutas de carga automática para lograr eso en modo classic
. Dado que Rails agrega automáticamente todos los subdirectorios de app
a las rutas de carga automática, tenemos otra situación en la que hay directorios raíz anidados, por lo que esa configuración ya no funciona. Principio similar que explicamos anteriormente con concerns
.
Si desea mantener esa estructura, deberá eliminar el subdirectorio de las rutas de carga automática en un inicializador:
ActiveSupport::Dependencies.autoload_paths.delete("#{Rails.root}/app/api")
6.8.7 Constantes Cargadas Automáticamente y Espacios de Nombres Explícitos
Si un espacio de nombres se define en un archivo, como Hotel
aquí:
app/models/hotel.rb # Define Hotel.
app/models/hotel/pricing.rb # Define Hotel::Pricing.
la constante Hotel
debe establecerse usando las palabras clave class
o module
. Por ejemplo:
class Hotel
end
es bueno.
Alternativas como
Hotel = Class.new
o
Hotel = Struct.new
no funcionarán, los objetos secundarios como Hotel::Pricing
no se encontrarán.
Esta restricción solo se aplica a espacios de nombres explícitos. Las clases y módulos que no definen un espacio de nombres se pueden definir usando esos idioms.
6.8.8 Un archivo, una constante (en el mismo nivel superior)
En el modo classic
técnicamente podría definir varias constantes en el mismo nivel superior y hacer que todas se recargaran. Por ejemplo, dado
# app/models/foo.rb
class Foo
end
class Bar
end
mientras que Bar
no podría ser cargado automáticamente, cargar automáticamente Foo
marcaría Bar
como cargado automáticamente también. Este no es el caso en modo zeitwerk
, necesita mover Bar
a su propio archivo bar.rb
. Un archivo, una constante.
Esto solo se aplica a las constantes en el mismo nivel superior como en el ejemplo anterior. Las clases y módulos internos están bien. Por ejemplo, considere
# app/models/foo.rb
class Foo
class InnerClass
end
end
Si la aplicación recarga Foo
, también recargará Foo::InnerClass
.
6.8.9 Spring y el Entorno test
Spring recarga el código de la aplicación si algo cambia. En el entorno test
, necesita habilitar la recarga para que eso funcione:
# config/environments/test.rb
config.cache_classes = false
De lo contrario, obtendrá este error:
reloading is disabled because config.cache_classes is true
6.8.10 Bootsnap
Bootsnap debe ser al menos la versión 1.4.2.
Además de eso, Bootsnap necesita deshabilitar la caché iseq debido a un error en el intérprete si se ejecuta Ruby 2.5. Asegúrese de depender al menos de Bootsnap 1.4.4 en ese caso.
6.8.11 config.add_autoload_paths_to_load_path
El nuevo punto de configuración config.add_autoload_paths_to_load_path
es true
de manera predeterminada para la compatibilidad con versiones anteriores, pero le permite optar por no agregar las rutas de carga automática a $LOAD_PATH
.
Esto tiene sentido en la mayoría de las aplicaciones, ya que nunca debería requerir un archivo en app/models
, por ejemplo, y Zeitwerk solo usa nombres de archivos absolutos internamente.
Al optar por no hacerlo, optimiza las búsquedas de $LOAD_PATH
(menos directorios para verificar) y ahorra trabajo y consumo de memoria de Bootsnap, ya que no necesita construir un índice para estos directorios.
6.8.12 Seguridad de Hilos
En modo clásico, la carga automática de constantes no es segura para hilos, aunque Rails tiene bloqueos en su lugar, por ejemplo, para hacer que las solicitudes web sean seguras para hilos cuando la carga automática está habilitada, como es común en el entorno de desarrollo.
La carga automática de constantes es segura para hilos en modo zeitwerk
. Por ejemplo, ahora puede cargar automáticamente en scripts multihilo ejecutados por el comando runner
.
6.8.13 Globos en config.autoload_paths
Tenga cuidado con configuraciones como
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Cada elemento de config.autoload_paths
debe representar el espacio de nombres de nivel superior (Object
) y no pueden estar anidados en consecuencia (con la excepción de los directorios concerns
explicados anteriormente).
Para solucionar esto, simplemente elimine los comodines:
config.autoload_paths << "#{config.root}/lib"
6.8.14 La carga ansiosa y la carga automática son consistentes
En modo classic
, si app/models/foo.rb
define Bar
, no podrá cargar automáticamente ese archivo, pero la carga ansiosa funcionará porque carga archivos de manera recursiva a ciegas. Esto puede ser una fuente de errores si prueba cosas primero cargando ansiosamente, la ejecución puede fallar más tarde cargando automáticamente.
En modo zeitwerk
, ambos modos de carga son consistentes, fallan y erran en los mismos archivos.
6.8.15 Cómo Usar el Cargador Automático Clásico en Rails 6
Las aplicaciones pueden cargar los valores predeterminados de Rails 6 y aún usar el cargador automático clásico configurando config.autoloader
de esta manera:
# config/application.rb
config.load_defaults 6.0
config.autoloader = :classic
Al usar el Cargador Automático Clásico en la aplicación Rails 6, se recomienda establecer el nivel de concurrencia en 1 en el entorno de desarrollo, para los servidores web y procesadores en segundo plano, debido a las preocupaciones de seguridad de hilos.
6.9 Cambio en el Comportamiento de Asignación de Active Storage
Con los valores de configuración predeterminados para Rails 5.2, asignar a una colección de archivos adjuntos declarados con has_many_attached
agrega nuevos archivos:
class User < ApplicationRecord
has_many_attached :highlights
end
user.highlights.attach(filename: "funky.jpg")
user.highlights.count # => 1
blob = ActiveStorage::Blob.create_after_upload!(filename: "town.jpg")
user.update!(highlights: [ blob ])
user.highlights.count # => 2
user.highlights.first.filename # => "funky.jpg"
user.highlights.second.filename # => "town.jpg"
Con los valores de configuración predeterminados para Rails 6.0, asignar a una colección de archivos adjuntos reemplaza los archivos existentes en lugar de agregarlos. Esto coincide con el comportamiento de Active Record al asignar a una asociación de colección:
user.highlights.attach(filename: "funky.jpg")
user.highlights.count # => 1
blob = ActiveStorage::Blob.create_after_upload!(filename: "town.jpg")
user.update!(highlights: [ blob ])
user.highlights.count # => 1
user.highlights.first.filename # => "town.jpg"
#attach
se puede usar para agregar nuevos archivos adjuntos sin eliminar los existentes:
blob = ActiveStorage::Blob.create_after_upload!(filename: "town.jpg")
user.highlights.attach(blob)
user.highlights.count # => 2
user.highlights.first.filename # => "funky.jpg"
user.highlights.second.filename # => "town.jpg"
Las aplicaciones existentes pueden optar por este nuevo comportamiento configurando config.active_storage.replace_on_assign_to_many
en true
. El comportamiento anterior será desaprobado en Rails 7.0 y eliminado en Rails 7.1.
6.10 Aplicaciones de Manejo de Excepciones Personalizadas
Las cabeceras de solicitud Accept
o Content-Type
inválidas ahora generarán una excepción. La aplicación de excepciones predeterminada config.exceptions_app
maneja específicamente ese error y lo compensa. Las aplicaciones de excepciones personalizadas deberán manejar ese error también, o tales solicitudes harán que Rails use la aplicación de excepciones de respaldo, que devuelve un 500 Internal Server Error
.
7 Actualización de Rails 5.1 a Rails 5.2
Para obtener más información sobre los cambios realizados en Rails 5.2, consulte las notas de lanzamiento.
7.1 Bootsnap
Rails 5.2 agrega el gem bootsnap en el Gemfile de la nueva aplicación generada. El comando app:update
lo configura en boot.rb
. Si desea usarlo, agréguelo en el Gemfile:
# Reduce los tiempos de arranque mediante el almacenamiento en caché; requerido en config/boot.rb
gem "bootsnap", require: false
De lo contrario, cambie el boot.rb
para no usar bootsnap.
7.2 La expiración en cookies firmadas o cifradas ahora está incrustada en los valores de las cookies
Para mejorar la seguridad, Rails ahora incrusta la información de expiración también en el valor de las cookies cifradas o firmadas.
Esta nueva información incrustada hace que esas cookies sean incompatibles con versiones de Rails anteriores a 5.2.
Si necesita que sus cookies sean leídas por 5.1 y versiones anteriores, o aún está validando su implementación de 5.2 y desea permitir que pueda revertir, establezca Rails.application.config.action_dispatch.use_authenticated_cookie_encryption
en false
.
8 Actualización de Rails 5.0 a Rails 5.1
Para obtener más información sobre los cambios realizados en Rails 5.1, consulte las notas de lanzamiento.
8.1 HashWithIndifferentAccess
de nivel superior está en desuso
Si su aplicación utiliza la clase HashWithIndifferentAccess
de nivel superior, debe mover su código lentamente para usar ActiveSupport::HashWithIndifferentAccess
.
Solo está en desuso suavemente, lo que significa que su código no se romperá en este momento y no se mostrará ninguna advertencia de desaprobación, pero esta constante se eliminará en el futuro.
Además, si tiene documentos YAML bastante antiguos que contienen volcados de tales objetos, es posible que necesite cargarlos y volcarlos nuevamente para asegurarse de que hagan referencia a la constante correcta y que cargarlos no se rompa en el futuro.
8.2 application.secrets
ahora se carga con todas las claves como símbolos
Si su aplicación almacena configuración anidada en config/secrets.yml
, todas las claves ahora se cargan como símbolos, por lo que el acceso usando cadenas debe cambiarse.
De:
Rails.application.secrets[:smtp_settings]["address"]
A:
Rails.application.secrets[:smtp_settings][:address]
8.3 Eliminado soporte desaprobado para :text
y :nothing
en render
Si sus controladores están usando render :text
, ya no funcionarán. El nuevo método de renderizar texto con tipo MIME de text/plain
es usar render :plain
.
Del mismo modo, render :nothing
también se ha eliminado y debe usar el método head
para enviar respuestas que solo contengan encabezados. Por ejemplo, head :ok
envía una respuesta 200 sin cuerpo para renderizar.
8.4 Eliminado soporte desaprobado de redirect_to :back
En Rails 5.0, redirect_to :back
fue desaprobado. En Rails 5.1, se eliminó por completo.
Como alternativa, use redirect_back
. Es importante tener en cuenta que redirect_back
también toma una opción fallback_location
que se utilizará en caso de que falte el HTTP_REFERER
.
redirect_back(fallback_location: root_path)
9 Actualización de Rails 4.2 a Rails 5.0
Para obtener más información sobre los cambios realizados en Rails 5.0, consulte las notas de lanzamiento.
9.1 Ruby 2.2.2+ requerido
A partir de Ruby on Rails 5.0 en adelante, Ruby 2.2.2+ es la única versión de Ruby compatible. Asegúrese de estar en la versión Ruby 2.2.2 o superior antes de continuar.
9.2 Los modelos de Active Record ahora heredan de ApplicationRecord por defecto
En Rails 4.2, un modelo de Active Record hereda de ActiveRecord::Base
. En Rails 5.0, todos los modelos heredan de ApplicationRecord
.
ApplicationRecord
es una nueva superclase para todos los modelos de la aplicación, análoga a los controladores de la aplicación que subclasan ApplicationController
en lugar de ActionController::Base
. Esto le da a las aplicaciones un único lugar para configurar el comportamiento del modelo en toda la aplicación.
Al actualizar de Rails 4.2 a Rails 5.0, necesita crear un archivo application_record.rb
en app/models/
y agregar el siguiente contenido:
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
Luego asegúrese de que todos sus modelos hereden de él.
9.3 Detener cadenas de devoluciones de llamada a través de throw(:abort)
En Rails 4.2, cuando una devolución de llamada 'before' devuelve false
en Active Record y Active Model, entonces se detiene toda la cadena de devoluciones de llamada. En otras palabras, las devoluciones de llamada 'before' sucesivas no se ejecutan, ni tampoco la acción envuelta en devoluciones de llamada.
En Rails 5.0, devolver false
en una devolución de llamada de Active Record o Active Model no tendrá este efecto secundario de detener la cadena de devoluciones de llamada. En su lugar, las cadenas de devoluciones de llamada deben detenerse explícitamente llamando a throw(:abort)
.
Cuando actualice de Rails 4.2 a Rails 5.0, devolver false
en ese tipo de devoluciones de llamada aún detendrá la cadena de devoluciones de llamada, pero recibirá una advertencia de desaprobación sobre este cambio próximo.
Cuando esté listo, puede optar por el nuevo comportamiento y eliminar la advertencia de desaprobación agregando la siguiente configuración a su config/application.rb
:
ActiveSupport.halt_callback_chains_on_return_false = false
Tenga en cuenta que esta opción no afectará a las devoluciones de llamada de Active Support, ya que nunca detuvieron la cadena cuando se devolvía cualquier valor.
Consulte #17227 para obtener más detalles.
9.4 ActiveJob ahora hereda de ApplicationJob por defecto
En Rails 4.2, un Active Job hereda de ActiveJob::Base
. En Rails 5.0, este comportamiento ha cambiado para heredar ahora de ApplicationJob
.
Al actualizar de Rails 4.2 a Rails 5.0, necesita crear un archivo application_job.rb
en app/jobs/
y agregar el siguiente contenido:
class ApplicationJob < ActiveJob::Base
end
Luego asegúrese de que todas sus clases de trabajo hereden de él.
Consulte #19034 para obtener más detalles.
9.5 Pruebas de Controladores de Rails
9.5.1 Extracción de algunos métodos auxiliares a rails-controller-testing
assigns
y assert_template
se han extraído al gem rails-controller-testing
. Para continuar usando estos métodos en sus pruebas de controlador, agregue gem "rails-controller-testing"
a su Gemfile
.
Si está usando RSpec para las pruebas, consulte la configuración adicional requerida en la documentación del gem.
9.5.2 Nuevo comportamiento al subir archivos
Si está utilizando ActionDispatch::Http::UploadedFile
en sus pruebas para subir archivos, necesitará cambiar para usar la clase similar Rack::Test::UploadedFile
en su lugar.
Consulte #26404 para obtener más detalles.
9.6 La carga automática está deshabilitada después de iniciar en el entorno de producción
La carga automática ahora está deshabilitada después de iniciar en el entorno de producción de manera predeterminada.
La carga ansiosa de la aplicación es parte del proceso de inicio, por lo que las constantes de nivel superior están bien y aún se cargan automáticamente, no es necesario requerir sus archivos.
Las constantes en lugares más profundos que solo se ejecutan en tiempo de ejecución, como los cuerpos de métodos regulares, también están bien porque el archivo que los define se habrá cargado ansiosamente durante el inicio.
Para la gran mayoría de las aplicaciones, este cambio no necesita ninguna acción. Pero en el caso muy raro de que su aplicación necesite carga automática mientras se ejecuta en producción, configure Rails.application.config.enable_dependency_loading
en true.
9.7 Serialización XML
ActiveModel::Serializers::Xml
se ha extraído de Rails al gem activemodel-serializers-xml
. Para continuar usando la serialización XML en su aplicación, agregue gem "activemodel-serializers-xml"
a su Gemfile
.
9.8 Eliminado soporte para adaptador de base de datos mysql
heredado
Rails 5 elimina el soporte para el adaptador de base de datos mysql
heredado. La mayoría de los usuarios deberían poder usar mysql2
en su lugar. Se convertirá en un gem separado cuando encontremos a alguien que lo mantenga.
9.9 Eliminado soporte para Debugger
debugger
no es compatible con Ruby 2.2, que es requerido por Rails 5. Use byebug
en su lugar.
9.10 Use bin/rails
para ejecutar tareas y pruebas
Rails 5 agrega la capacidad de ejecutar tareas y pruebas a través de bin/rails
en lugar de rake. Generalmente, estos cambios están en paralelo con rake, pero algunos se portaron por completo.
Para usar el nuevo ejecutor de pruebas, simplemente escriba bin/rails test
.
rake dev:cache
ahora es bin/rails dev:cache
.
Ejecute bin/rails
dentro del directorio raíz de su aplicación para ver la lista de comandos disponibles.
9.11 ActionController::Parameters
ya no hereda de HashWithIndifferentAccess
Llamar a params
en su aplicación ahora devolverá un objeto en lugar de un hash. Si sus parámetros ya están permitidos, entonces no necesitará hacer ningún cambio. Si está utilizando map
y otros métodos que dependen de poder leer el hash independientemente de permitted?
, necesitará actualizar su aplicación para primero permitir y luego convertir a un hash.
params.permit([:proceed_to, :return_to]).to_h
9.12 protect_from_forgery
ahora predetermina prepend: false
protect_from_forgery
predetermina prepend: false
, lo que significa que se insertará en la cadena de devoluciones de llamada en el punto en que lo llame en su aplicación. Si desea que protect_from_forgery
siempre se ejecute primero, debe cambiar su aplicación para usar protect_from_forgery prepend: true
.
9.13 El manejador de plantillas predeterminado ahora es RAW
Los archivos sin un manejador de plantillas en su extensión se renderizarán usando el manejador raw. Anteriormente, Rails renderizaba archivos usando el manejador de plantillas ERB.
Si no desea que su archivo sea manejado a través del manejador raw, debe agregar una extensión a su archivo que pueda ser analizada por el manejador de plantillas apropiado.
9.14 Agregado coincidencia de comodines para dependencias de plantillas
Ahora puede usar coincidencia de comodines para sus dependencias de plantillas. Por ejemplo, si estaba definiendo sus plantillas de esta manera:
<% # Template Dependency: recordings/threads/events/subscribers_changed %>
<% # Template Dependency: recordings/threads/events/completed %>
<% # Template Dependency: recordings/threads/events/uncompleted %>
Ahora puede simplemente llamar a la dependencia una vez con un comodín.
<% # Template Dependency: recordings/threads/events/* %>
9.15 ActionView::Helpers::RecordTagHelper
movido a un gem externo (record_tag_helper)
content_tag_for
y div_for
se han eliminado en favor de simplemente usar content_tag
. Para continuar usando los métodos anteriores, agregue el gem record_tag_helper
a su Gemfile
:
gem "record_tag_helper", "~> 1.0"
Consulte #18411 para obtener más detalles.
9.16 Eliminado soporte para el gem protected_attributes
El gem protected_attributes
ya no es compatible en Rails 5.
9.17 Eliminado soporte para el gem activerecord-deprecated_finders
El gem activerecord-deprecated_finders
ya no es compatible en Rails 5.
9.18 El orden de prueba predeterminado de ActiveSupport::TestCase
ahora es aleatorio
Cuando se ejecutan pruebas en su aplicación, el orden predeterminado ahora es :random
en lugar de :sorted
. Use la siguiente opción de configuración para establecerlo de nuevo en :sorted
.
# config/environments/test.rb
Rails.application.configure do
config.active_support.test_order = :sorted
end
9.19 ActionController::Live
se convirtió en un Concern
Si incluye ActionController::Live
en otro módulo que se incluye en su controlador, entonces también debe extender el módulo con ActiveSupport::Concern
. Alternativamente, puede usar el gancho self.included
para incluir ActionController::Live
directamente en el controlador una vez que se incluya StreamingSupport
.
Esto significa que si su aplicación solía tener su propio módulo de transmisión, el siguiente código se rompería en producción:
# Esta es una solución para controladores transmitidos que realizan autenticación con Warden/Devise.
# Consulte https://github.com/plataformatec/devise/issues/2332
# La autenticación en el enrutador es otra solución como se sugi
Comentarios
Se te anima a ayudar a mejorar la calidad de esta guía.
Por favor contribuye si ves algún error tipográfico o errores fácticos. Para comenzar, puedes leer nuestra sección de contribuciones a la documentación.
También puedes encontrar contenido incompleto o cosas que no están actualizadas. Por favor agrega cualquier documentación faltante para main. Asegúrate de revisar Guías Edge primero para verificar si los problemas ya están resueltos o no en la rama principal. Revisa las Guías de Ruby on Rails para estilo y convenciones.
Si por alguna razón detectas algo que corregir pero no puedes hacerlo tú mismo, por favor abre un issue.
Y por último, pero no menos importante, cualquier tipo de discusión sobre la documentación de Ruby on Rails es muy bienvenida en el Foro oficial de Ruby on Rails.