1 Consejos generales
Antes de intentar actualizar una aplicación existente, debes asegurarte de tener una buena razón para hacerlo. Debes equilibrar varios factores: la necesidad de nuevas características, la dificultad creciente de encontrar soporte para código antiguo y tu tiempo y habilidades disponibles, por nombrar algunos.
1.1 Cobertura de pruebas
La mejor manera de asegurarte de que tu aplicación siga funcionando después de la actualización es tener una buena cobertura de pruebas antes de comenzar el proceso. Si no tienes pruebas automatizadas que ejerciten la mayor parte de tu aplicación, deberás pasar tiempo ejercitando manualmente todas las partes que han cambiado. En el caso de una actualización de Rails, eso significará cada pieza de funcionalidad en la aplicación. Hazte un favor y asegúrate de que tu 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 lanza:
- Rails 7 requiere Ruby 2.7.0 o una versión más nueva.
- Rails 6 requiere Ruby 2.5.0 o una versión más nueva.
- Rails 5 requiere Ruby 2.2.2 o una versión más nueva.
Es una buena idea actualizar Ruby y Rails por separado. Primero actualiza a la última versión de Ruby que puedas y luego actualiza Rails.
1.3 El proceso de actualización
Cuando cambias las versiones de Rails, es mejor avanzar lentamente, una versión menor a la vez, para aprovechar al máximo las advertencias de deprecación. Los números de versión de Rails tienen la forma Mayor.Menor.Parche. Las versiones Mayor y Menor pueden realizar cambios en la API pública, lo que puede causar errores en tu aplicación. Las versiones de Parche solo incluyen correcciones de errores y no cambian ninguna API pública.
El proceso debería seguir los siguientes pasos:
- Escribe pruebas y asegúrate de que pasen.
- Muévete a la última versión de parche después de tu versión actual.
- Corrige las pruebas y las características obsoletas.
- Muévete a la última versión de parche de la siguiente versión menor.
Repite este proceso hasta que alcances tu versión objetivo de Rails.
1.3.1 Moverse entre versiones
Para moverte entre versiones:
- Cambia el número de versión de Rails en el
Gemfile
y ejecutabundle update
. - Cambia las versiones de los paquetes de JavaScript de Rails en
package.json
y ejecutayarn install
, si estás utilizando Webpacker. - Ejecuta la tarea de actualización.
- Ejecuta tus pruebas.
Puedes encontrar una lista de todas las gemas de Rails lanzadas 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
, ejecuta este comando.
Esto te ayudará con la creación de nuevos archivos y cambios en los archivos antiguos en una sesión interactiva.
$ bin/rails app:update
exist config
conflict config/application.rb
Sobrescribir /myapp/config/application.rb? (ingresa "h" para obtener ayuda) [Ynaqdh]
force config/application.rb
create config/initializers/new_framework_defaults_7_0.rb
...
No olvides revisar las diferencias para ver si hubo algún cambio inesperado.
1.5 Configurar los valores predeterminados del framework
Es posible que la nueva versión de Rails tenga valores predeterminados de configuración diferentes a la versión anterior. Sin embargo, después de seguir los pasos descritos anteriormente, tu aplicación seguirá ejecutándose con los valores predeterminados de configuración de la versión anterior de Rails. Esto se debe a que el valor de config.load_defaults
en config/application.rb
aún no ha sido cambiado.
Para permitirte actualizar a los nuevos valores predeterminados de forma gradual, 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). Debes habilitar los nuevos valores predeterminados de configuración descomentándolos en el archivo; esto se puede hacer gradualmente en varias implementaciones. Una vez que tu aplicación esté lista para ejecutarse con los nuevos valores predeterminados, puedes eliminar este archivo y cambiar el valor de config.load_defaults
.
2 Actualización de Rails 7.0 a Rails 7.1
Para obtener más información sobre los cambios realizados en Rails 7.1, consulta las notas de lanzamiento.
2.1 Las rutas cargadas automáticamente ya no están en la ruta de carga
A partir de Rails 7.1, todas las rutas gestionadas por el cargador automático ya no se agregarán a $LOAD_PATH
.
Esto significa que no será posible cargarlas con una llamada manual a require
, en su lugar, se puede hacer referencia a la clase o módulo.
Reducir el tamaño de $LOAD_PATH
acelera las llamadas a require
para aplicaciones que no utilizan bootsnap
y reduce el
tamaño de la caché de bootsnap
para las demás.
2.2 ActiveStorage::BaseController
ya no incluye la preocupación por la transmisión
Los controladores de la aplicación que heredan de ActiveStorage::BaseController
y utilizan la transmisión para implementar la lógica personalizada de servir archivos ahora deben incluir explícitamente el módulo ActiveStorage::Streaming
.
2.3 MemCacheStore
y RedisCacheStore
ahora utilizan la agrupación de conexiones de forma predeterminada
Se ha agregado la gema connection_pool
como una dependencia de la gema activesupport
,
y MemCacheStore
y RedisCacheStore
ahora utilizan la agrupación de conexiones de forma predeterminada.
Si no desea utilizar la 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 Caché con Rails para obtener más información.
2.4 SQLite3Adapter
ahora está configurado para utilizarse 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, luego 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 que no existe. Consulte la documentación de SQLite para obtener más detalles: SQLite documentation.
Si no desea utilizar SQLite3Adapter
en modo estricto, puede deshabilitar este comportamiento:
# config/application.rb
config.active_record.sqlite3_adapter_strict_strings_by_default = false
2.5 Se admite múltiples rutas de vista previa para ActionMailer::Preview
La opción config.action_mailer.preview_path
está en desuso a favor de config.action_mailer.preview_paths
. Agregar rutas a esta opción de configuración hará que se utilicen esas rutas en la búsqueda de vistas previas de correo.
config.action_mailer.preview_paths << "#{Rails.root}/lib/mailer_previews"
2.6 config.i18n.raise_on_missing_translations = true
ahora genera un error en caso de falta de traducción.
Anteriormente, solo generaba un error cuando se llamaba en una vista o controlador. Ahora generará un error cada vez que se proporcione una clave no reconocida a I18n.t
.
# 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 establecer 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.
3 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 la versión.
3.1 El comportamiento de ActionView::Helpers::UrlHelper#button_to
ha cambiado
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 utilizando 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)))
3.2 Spring
Si su aplicación utiliza Spring, debe actualizarse a al menos la versión 3.0.0. De lo contrario, obtendrá el siguiente error:
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
.
3.3 Sprockets ahora es una dependencia opcional
La gema rails
ya no depende de sprockets-rails
. Si su aplicación todavía necesita usar Sprockets,
asegúrese de agregar sprockets-rails
a su Gemfile.
gem "sprockets-rails"
3.4 Las aplicaciones deben ejecutarse en modo zeitwerk
Las aplicaciones que siguen ejecutándose en modo classic
deben cambiar al modo zeitwerk
. Consulte la guía Classic to Zeitwerk HOWTO para obtener más detalles.
3.5 Se ha eliminado el setter config.autoloader=
En Rails 7 no hay un punto de configuración para establecer el modo de carga automática, se ha eliminado config.autoloader=
. Si lo tenía configurado en :zeitwerk
por alguna razón, simplemente elimínelo.
3.6 Se ha eliminado la API privada de ActiveSupport::Dependencies
Se ha eliminado la API privada de ActiveSupport::Dependencies
. Esto incluye métodos como hook!
, unhook!
, depend_on
, require_or_load
, mechanism
y muchos otros.
Algunos aspectos destacados:
- Si utilizaba
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
, tanto de lectura como de escritura, debe reemplazarse accediendo aconfig.cache_classes
en consecuencia.Si desea rastrear la actividad del cargador automático,
ActiveSupport::Dependencies.verbose=
ya no está disponible, simplemente agregueRails.autoloaders.log!
enconfig/application.rb
. También se han eliminado las clases o módulos internos auxiliares, comoActiveSupport::Dependencies::Reference
,ActiveSupport::Dependencies::Blamable
y otros.
3.7 Carga automática durante la inicialización
Las aplicaciones que cargaban automáticamente constantes recargables durante la inicialización fuera de los bloques to_prepare
descargaban esas constantes y emitían esta advertencia desde Rails 6.0:
ADVERTENCIA DE DEPRECIACIÓN: La inicialización cargó automáticamente la constante ....
Poder hacer esto está en desuso. La carga automática durante la inicialización será una condición de error en futuras versiones de Rails.
...
Si aún obtiene 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á un NameError
en Rails 7.
3.8 Posibilidad 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 se puede cargar automáticamente desde esas rutas. En particular, se puede cargar automáticamente desde allí durante la inicialización. Son gestionados por el cargador automático Rails.autoloaders.once
, que no se recarga, solo carga automáticamente/carga ansiosa.
Si configuró esta opción después de que se haya procesado la configuración de los entornos y está obteniendo un FrozenError
, simplemente mueva el código.
3.9 ActionDispatch::Request#content_type
ahora devuelve el encabezado Content-Type tal como está.
Anteriormente, el valor devuelto por ActionDispatch::Request#content_type
NO contenía la parte del conjunto de caracteres.
Este comportamiento cambió para devolver el encabezado Content-Type que contiene la parte del conjunto de caracteres tal como está.
Si solo desea el tipo MIME, utilice 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"
3.10 El cambio de clase de resumen del generador de claves requiere un rotador de cookies
La clase de resumen 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 utilizando la antigua clase de resumen, es necesario registrar un rotador. No hacerlo puede resultar en que los usuarios tengan sus sesiones invalidadas durante la actualización.
A continuación se muestra 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
3.11 Cambio de clase de resumen para ActiveSupport::Digest a SHA256
La clase de resumen predeterminada para ActiveSupport::Digest está cambiando de SHA1 a SHA256. Esto tiene consecuencias en cosas como las Etags que cambiarán y las claves de caché también. Cambiar estas claves puede tener un impacto en las tasas de aciertos en caché, así que tenga cuidado y esté atento a esto al actualizar al nuevo hash.
3.12 Nuevo formato de serialización de ActiveSupport::Cache
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, una vez que todos los procesos de Rails
hayan sido actualizados, 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.
3.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 desde negro. Este cambio requiere FFmpeg v3.4+.
3.14 El procesador de variantes predeterminado de Active Storage cambió a :vips
Para nuevas aplicaciones, la transformación de imágenes utilizará 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 se está deprecando, por lo que está bien seguir usándola.
Para migrar una aplicación existente a libvips, establezca:
ruby
Rails.application.config.active_storage.variant_processor = :vips
Luego deberás cambiar el código de transformación de imágenes existente a los macros image_processing
y reemplazar las opciones de ImageMagick con las opciones de libvips.
3.14.1 Reemplazar resize con resize_to_limit
- variant(resize: "100x")
+ variant(resize_to_limit: [100, nil])
Si no haces esto, cuando cambies a vips verás este error: no implicit conversion to float from string
.
3.14.2 Usar un array al recortar
- variant(crop: "1920x1080+0+0")
+ variant(crop: [0, 0, 1920, 1080])
Si no haces esto al migrar a vips, verás el siguiente error: unable to call crop: you supplied 2 arguments, but operation needs 5
.
3.14.3 Ajustar 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. 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. Ejemplo: una imagen de 125x125 y un recorte de[50, 50, 100, 100]
Si no haces esto al migrar a vips, verás el siguiente error: extract_area: bad extract area
3.14.4 Ajustar el color de fondo utilizado para resize_and_pad
Vips utiliza negro como color de fondo predeterminado en resize_and_pad
, en lugar de blanco como ImageMagick. Soluciónalo utilizando la opción background
:
- variant(resize_and_pad: [300, 300])
+ variant(resize_and_pad: [300, 300, background: [255]])
3.14.5 Eliminar cualquier rotación basada en EXIF
Vips rotará automáticamente las imágenes utilizando el valor EXIF al procesar variantes. Si estabas almacenando valores de rotación de fotos cargadas por el usuario para aplicar la rotación con ImageMagick, debes dejar de hacerlo:
- variant(format: :jpg, rotate: rotation_value)
+ variant(format: :jpg)
3.14.6 Reemplazar monochrome con colourspace
Vips utiliza una opción diferente para crear imágenes monocromáticas:
- variant(monochrome: true)
+ variant(colourspace: "b-w")
3.14.7 Cambiar 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 })
3.14.8 Implementar en producción
Active Storage codifica en la URL de la imagen la lista de transformaciones que deben realizarse. Si tu aplicación está almacenando en caché estas URL, tus imágenes se romperán después de implementar el nuevo código en producción. Por esta razón, debes invalidar manualmente las claves de caché afectadas.
Por ejemplo, si tienes algo como esto en una vista:
<% @products.each do |product| %>
<% cache product do %>
<%= image_tag product.cover_photo.variant(resize: "200x") %>
<% end %>
<% end %>
Puedes 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 %>
3.15 La versión de Rails ahora se incluye en el volcado del 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 utilizando los nuevos valores predeterminados de 7.0, Rails ahora incluye la versión del framework en el volcado del esquema.
Antes de cargar el esquema por primera vez en Rails 7.0, asegúrate de ejecutar rails app:update
para asegurarte de que la versión del esquema se incluya en el volcado del esquema.
El archivo de esquema se verá así:
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# This file is the source Rails uses to define your schema when running `bin/rails
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[6.1].define(version: 2022_01_28_123512) do
NOTA: La primera vez que se volcó el esquema con Rails 7.0, verá muchos cambios en ese archivo, incluida alguna información de columna. Asegúrese de revisar el nuevo contenido del archivo de esquema y confirmarlo en su repositorio.
4 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 la versión.
4.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 se deprecó 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')
4.2 El tipo de contenido de la respuesta al usar respond_to#any
El encabezado Content-Type devuelto en la respuesta puede diferir de lo que devolvía Rails 6.0,
más específicamente si su aplicación usa respond_to { |format| format.any }
.
El tipo de contenido 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 incorrecto 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 recomienda especificar los formatos que acepta su acción, es decir:
format.any(:xml, :json) { render request.format.to_sym => @people }
4.3 ActiveSupport::Callbacks#halted_callback_hook
ahora recibe un segundo argumento
Active Support le permite anular el halted_callback_hook
cada vez que un callback
detiene la cadena. Este método ahora recibe un segundo argumento que es el nombre del callback que se está deteniendo.
Si tiene clases que anulan este método, asegúrese de que acepten dos argumentos. Tenga en cuenta que este es un cambio que rompe la compatibilidad sin un ciclo de deprecació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("No se pudo #{callback_name}r el libro")
end
end
4.4 El método de clase helper
en los controladores utiliza 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 es necesario hacer nada.
Técnicamente, sin embargo, los controladores podrían configurar helpers_path
para que apunte a un directorio en $LOAD_PATH
que no estuviera 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
.
4.5 La redirección a HTTPS desde HTTP ahora utilizará 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 se ha cambiado a 308
según se define en https://tools.ietf.org/html/rfc7538.
4.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 forma predeterminada para usar mini_magick
en segundo plano, 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, es posible que desee cambiar las llamadas resize
en bruto a las 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])
4.7 Nueva clase ActiveModel::Error
Ahora los errores 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 mostrarán advertencias de deprecación para corregir en Rails 7.0.
Más información sobre este cambio y detalles sobre los cambios en la API se pueden encontrar en este PR.
5 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 la versión.
5.1 Uso de Webpacker
Webpacker es el compilador de JavaScript predeterminado para Rails 6. Pero si estás actualizando la aplicación, no está activado de forma predeterminada. Si quieres usar Webpacker, inclúyelo en tu Gemfile e instálalo:
gem "webpacker"
$ bin/rails webpacker:install
5.2 Forzar SSL
El método force_ssl
en los controladores ha sido deprecado y se eliminará en
Rails 6.1. Se recomienda habilitar config.force_ssl
para hacer cumplir las conexiones HTTPS
en toda tu aplicación. Si necesitas eximir ciertos puntos finales
de la redirección, puedes usar config.ssl_options
para configurar ese comportamiento.
5.3 Los metadatos de propósito y caducidad ahora están incrustados dentro de las cookies firmadas y encriptadas para aumentar la seguridad
Para mejorar la seguridad, Rails incrusta los metadatos de propósito y caducidad dentro del valor de las cookies firmadas o encriptadas.
Rails puede entonces frustrar los ataques que intentan copiar el valor firmado/encriptado de una cookie y usarlo como el valor de otra cookie.
Estos nuevos metadatos incrustados hacen que esas cookies sean incompatibles con versiones de Rails anteriores a 6.0.
Si necesitas que tus cookies sean leídas por Rails 5.2 y anteriores, o aún estás validando tu implementación de 6.0 y quieres
poder revertir, establece
Rails.application.config.action_dispatch.use_cookies_with_metadata
en false
.
5.4 Todos los paquetes npm se han movido al ámbito @rails
Si anteriormente estabas cargando alguno de los paquetes actioncable
, activestorage
,
o rails-ujs
a través de npm/yarn, debes actualizar los nombres de estas
dependencias antes de poder actualizarlas a 6.0.0
:
actioncable → @rails/actioncable
activestorage → @rails/activestorage
rails-ujs → @rails/ujs
5.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 que rompen partes opcionales de la API de JavaScript de Action Cable:
La configuración del adaptador WebSocket y del adaptador de registro se ha movido de propiedades de
ActionCable
a propiedades deActionCable.adapters
. Si estás configurando estos adaptadores, necesitarás hacer 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 por la propiedadActionCable.logger.enabled
. Si estás usando estos métodos, necesitarás hacer estos cambios:- ActionCable.startDebugging() + ActionCable.logger.enabled = true
- ActionCable.stopDebugging() + ActionCable.logger.enabled = false
5.6 ActionDispatch::Response#content_type
ahora devuelve el encabezado Content-Type sin modificaciones
Anteriormente, el valor devuelto por ActionDispatch::Response#content_type
NO contenía la parte de conjunto de caracteres.
Este comportamiento ha cambiado para incluir la parte de conjunto de caracteres previamente omitida.
Si solo quieres el tipo MIME, utiliza 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"
5.7 Nueva configuración config.hosts
Rails ahora tiene una nueva configuración config.hosts
por motivos de seguridad. Esta configuración
tiene como valor predeterminado localhost
en desarrollo. Si usas otros dominios en desarrollo,
necesitas permitirlos de esta manera:
# 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 de forma predeterminada, lo que significa que Rails
no validará el host en absoluto. Opcionalmente, puedes agregarlos si deseas
validarlo en producción.
5.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ás utilizando los valores predeterminados de una versión anterior de Rails, puedes habilitar zeitwerk de la siguiente manera:
# config/application.rb
config.autoloader = :zeitwerk
5.8.1 API pública
En general, las aplicaciones no necesitan utilizar la API de Zeitwerk directamente. Rails configura las cosas según el contrato existente: config.autoload_paths
, config.cache_classes
, etc.
Si bien las aplicaciones deben adherirse a esa interfaz, el objeto de carga de Zeitwerk real se puede acceder como
Rails.autoloaders.main
Eso puede ser útil si necesitas precargar clases de herencia de tabla única (STI) o configurar un inflector personalizado, por ejemplo.
5.8.2 Estructura del proyecto
Si la aplicación que se está actualizando se carga automáticamente correctamente, la estructura del proyecto debería ser compatible en su mayoría.
Sin embargo, el modo classic
infiere los nombres de archivo a partir de los nombres de constante faltantes (underscore
), mientras que el modo zeitwerk
infiere los nombres de constante a partir de los nombres de archivo (camelize
). Estos ayudantes no siempre son inversos entre sí, en particular si se involucran 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
Espera, estoy cargando la aplicación.
¡Todo está bien!
5.8.3 require_dependency
Se han eliminado todos los casos conocidos de require_dependency
, debes buscar en el proyecto y eliminarlos.
Si tu aplicación utiliza la herencia de tabla única, consulta la sección Herencia de tabla única de la guía Autoloading and Reloading Constants (Modo Zeitwerk).
5.8.4 Nombres calificados en las definiciones de clases y módulos
Ahora puedes usar de manera robusta rutas constantes en las definiciones de clases y módulos:
# La carga automática en el cuerpo de esta clase coincide ahora con la semántica de Ruby.
class Admin::UsersController < ApplicationController
# ...
end
Un detalle a tener en cuenta es que, dependiendo del orden de ejecución, el cargador automático clásico a veces podía cargar Foo::Wadus
en
class Foo::Bar
Wadus
end
Esto no coincide con la semántica de Ruby porque Foo
no está en el anidamiento, y no funcionará en el modo zeitwerk
. Si encuentras un caso así, puedes usar el nombre calificado Foo::Wadus
:
class Foo::Bar
Foo::Wadus
end
o agregar Foo
al anidamiento:
module Foo
class Bar
Wadus
end
end
5.8.5 Concerns
Puedes cargar automáticamente y cargar de manera anticipada 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. Por lo tanto, app/models/concerns/foo.rb
debe definir Foo
, no Concerns::Foo
.
El espacio de nombres Concerns::
funcionaba con el cargador automático clásico como un efecto secundario de la implementación, pero en realidad no era un comportamiento deseado. Una aplicación que utiliza Concerns::
debe cambiar el nombre de esas clases y módulos para poder ejecutarse en el modo zeitwerk
.
5.8.6 Tener app
en las rutas de carga automática
Algunos proyectos desean que algo como app/api/base.rb
defina API::Base
y agregan app
a las rutas de carga automática para lograrlo en el 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. El mismo principio que explicamos anteriormente con concerns
.
Si deseas mantener esa estructura, deberás eliminar el subdirectorio de las rutas de carga automática en un inicializador:
ActiveSupport::Dependencies.autoload_paths.delete("#{Rails.root}/app/api")
5.8.7 Constantes cargadas automáticamente y espacios de nombres explícitos
Si se define un espacio de nombres 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 utilizando las palabras clave class
o module
. Por ejemplo:
class Hotel
end
es correcto.
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 los espacios de nombres explícitos. Las clases y módulos que no definen un espacio de nombres se pueden definir utilizando esos métodos.
5.8.8 Un archivo, una constante (en el mismo nivel superior)
En el modo classic
, técnicamente se podían definir varias constantes en el mismo nivel superior y todas se recargaban. Por ejemplo, dado
# app/models/foo.rb
class Foo
end
class Bar
end
mientras que Bar
no se podía cargar automáticamente, cargar Foo
marcaría a Bar
como cargado automáticamente también. Esto no ocurre en el modo zeitwerk
, debes 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, considera
# app/models/foo.rb
class Foo
class InnerClass
end
end
Si la aplicación recarga Foo
, también recargará Foo::InnerClass
.
5.8.9 Spring y el entorno test
Spring recarga el código de la aplicación si algo cambia. En el entorno test
, debes habilitar la recarga para que funcione:
# config/environments/test.rb
config.cache_classes = false
De lo contrario, obtendrás este error:
la recarga está desactivada porque config.cache_classes es true
5.8.10 Bootsnap
Bootsnap debe ser al menos la versión 1.4.2.
Además de eso, Bootsnap necesita deshabilitar la caché de iseq debido a un error en el intérprete si se ejecuta Ruby 2.5. Asegúrate de depender al menos de Bootsnap 1.4.4 en ese caso.
5.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 forma predeterminada por compatibilidad con versiones anteriores, pero te 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 debes requerir un archivo en app/models
, por ejemplo, y Zeitwerk solo utiliza nombres de archivo absolutos internamente.
Al optar por la opción de exclusión, se optimizan las búsquedas en $LOAD_PATH
(menos directorios que verificar) y se ahorra trabajo y consumo de memoria en Bootsnap, ya que no necesita construir un índice para estos directorios.
5.8.12 Seguridad en hilos
En el modo clásico, la carga automática de constantes no es segura en hilos, aunque Rails tiene bloqueos implementados, por ejemplo, para hacer que las solicitudes web sean seguras en 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 en hilos en el modo zeitwerk
. Por ejemplo, ahora se puede cargar automáticamente en scripts multihilo ejecutados por el comando runner
.
5.8.13 Comodines en config.autoload_paths
Tenga cuidado con las 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"
5.8.14 La carga ansiosa y la carga automática son consistentes
En el modo clásico
, si app/models/foo.rb
define Bar
, no podrá cargar automáticamente ese archivo, pero la carga ansiosa funcionará porque carga archivos de forma recursiva a ciegas. Esto puede ser una fuente de errores si se prueban las cosas primero con carga ansiosa, la ejecución puede fallar más tarde con la carga automática.
En el modo zeitwerk
, ambos modos de carga son consistentes, fallan y generan errores en los mismos archivos.
5.8.15 Cómo usar el cargador automático clásico en Rails 6
Las aplicaciones pueden cargar las configuraciones predeterminadas de Rails 6 y seguir utilizando el cargador automático clásico configurando config.autoloader
de esta manera:
# config/application.rb
config.load_defaults 6.0
config.autoloader = :classic
Cuando se utiliza el cargador automático clásico en una aplicación de Rails 6, se recomienda establecer el nivel de concurrencia en 1 en el entorno de desarrollo, para los servidores web y los procesadores en segundo plano, debido a las preocupaciones de seguridad en hilos.
5.9 Cambio en el comportamiento de asignación de Active Storage
Con la configuración predeterminada para Rails 5.2, al asignar a una colección de archivos adjuntos declarados con has_many_attached
, se agregan 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 la configuración predeterminada para Rails 6.0, al asignar a una colección de archivos adjuntos se reemplazan los archivos existentes en lugar de agregar nuevos. 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 se eliminará en Rails 7.0 y se eliminará por completo en Rails 7.1.
5.10 Aplicaciones de manejo de excepciones personalizadas
Las cabeceras de solicitud Accept
o Content-Type
no válidas ahora generarán una excepción. La configuración predeterminada config.exceptions_app
maneja específicamente ese error y lo compensa. Las aplicaciones de excepciones personalizadas también deberán manejar ese error, de lo contrario, Rails utilizará la aplicación de excepciones de respaldo, que devuelve un 500 Internal Server Error
.
6 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 la versión.
6.1 Bootsnap
Rails 5.2 agrega la gema bootsnap en el Gemfile de la aplicación recién generada. El comando app:update
lo configura en boot.rb
. Si desea usarlo, agreguelo al Gemfile:
# Reduce los tiempos de arranque mediante el almacenamiento en caché; requerido en config/boot.rb
gem 'bootsnap', require: false
De lo contrario, cambie boot.rb
para no usar bootsnap.
6.2 El vencimiento en las cookies firmadas o encriptadas ahora está incrustado en los valores de las cookies
Para mejorar la seguridad, Rails ahora incrusta la información de vencimiento también en el valor de las cookies firmadas o encriptadas.
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 la versión 5.1 y anteriores, o aún está validando su implementación de la versión 5.2 y desea permitir el retroceso, configure Rails.application.config.action_dispatch.use_authenticated_cookie_encryption
en false
.
7 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 la versión.
7.1 La clase HashWithIndifferentAccess
de nivel superior está obsoleta
Si su aplicación utiliza la clase HashWithIndifferentAccess
de nivel superior, debe cambiar lentamente su código para utilizar en su lugar ActiveSupport::HashWithIndifferentAccess
.
Solo está suavemente obsoleto, lo que significa que su código no se romperá en este momento y no se mostrará ninguna advertencia de obsolescencia, pero esta constante se eliminará en el futuro.
Además, si tiene documentos YAML bastante antiguos que contienen volcados de dichos objetos, es posible que deba cargarlos y volcarlos nuevamente para asegurarse de que hagan referencia a la constante correcta y que su carga no se rompa en el futuro.
7.2 application.secrets
ahora se carga con todas las claves como símbolos
Si su aplicación almacena una configuración anidada en config/secrets.yml
, todas las claves ahora se cargan como símbolos, por lo que el acceso utilizando cadenas debe cambiarse.
De:
Rails.application.secrets[:smtp_settings]["address"]
A:
Rails.application.secrets[:smtp_settings][:address]
7.3 Se eliminó el soporte obsoleto de :text
y :nothing
en render
Si sus controladores están utilizando render :text
, ya no funcionarán. El nuevo método para renderizar texto con el tipo MIME text/plain
es utilizar render :plain
.
De manera similar, se eliminó render :nothing
y debe utilizar el método head
para enviar respuestas que contengan solo encabezados. Por ejemplo, head :ok
envía una respuesta 200 sin cuerpo para renderizar.
7.4 Se eliminó el soporte obsoleto de redirect_to :back
En Rails 5.0, redirect_to :back
fue declarado obsoleto. En Rails 5.1, se eliminó por completo.
Como alternativa, use redirect_back
. Es importante tener en cuenta que redirect_back
también acepta una opción fallback_location
que se utilizará en caso de que falte el HTTP_REFERER
.
redirect_back(fallback_location: root_path)
8 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 la versión.
8.1 Se requiere Ruby 2.2.2+
A partir de Ruby on Rails 5.0, solo se admite la versión de Ruby 2.2.2+. Asegúrese de tener la versión de Ruby 2.2.2 o superior antes de continuar.
8.2 Los modelos de Active Record ahora heredan de ApplicationRecord de forma predeterminada
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 heredan de ApplicationController
en lugar de ActionController::Base
. Esto proporciona a las aplicaciones un único lugar para configurar el comportamiento del modelo en toda la aplicación.
Cuando actualice de Rails 4.2 a Rails 5.0, debe 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.
8.3 Detención de cadenas de devolución de llamada mediante throw(:abort)
En Rails 4.2, cuando una devolución de llamada 'before' devuelve false
en Active Record y Active Model, se detiene toda la cadena de devolución de llamada. En otras palabras, las devoluciones de llamada 'before' sucesivas no se ejecutan y la acción envuelta en devoluciones de llamada tampoco se ejecuta.
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 devolución de llamada. En su lugar, las cadenas de devolución 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 seguirá deteniendo la cadena de devolución de llamada, pero recibirá una advertencia de obsolescencia sobre este próximo cambio.
Cuando esté listo, puede optar por el nuevo comportamiento y eliminar la advertencia de obsolescencia 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á 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.
8.4 ActiveJob ahora hereda de ApplicationJob de forma predeterminada
En Rails 4.2, un Active Job hereda de ActiveJob::Base
. En Rails 5.0, este comportamiento ha cambiado y ahora hereda de ApplicationJob
.
Cuando actualice de Rails 4.2 a Rails 5.0, debe 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.
8.5 Pruebas de controladores de Rails
8.5.1 Extracción de algunos métodos auxiliares a rails-controller-testing
assigns
y assert_template
se han extraído a la gema rails-controller-testing
. Para seguir utilizando estos métodos en sus pruebas de controladores, agregue gem 'rails-controller-testing'
a su Gemfile
.
Si está utilizando RSpec para las pruebas, consulte la documentación de la gema para ver la configuración adicional requerida.
8.5.2 Nuevo comportamiento al cargar archivos
Si está utilizando ActionDispatch::Http::UploadedFile
en sus pruebas para cargar archivos, deberá cambiar para usar la clase similar Rack::Test::UploadedFile
.
Ver #26404 para más detalles.
8.6 La carga automática está desactivada después de arrancar en el entorno de producción
La carga automática ahora está desactivada después de arrancar en el entorno de producción de forma predeterminada.
La carga ansiosa de la aplicación es parte del proceso de arranque, 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 los métodos regulares, también están bien porque el archivo que las define se habrá cargado ansiosamente durante el arranque.
Para la gran mayoría de las aplicaciones, este cambio no requiere ninguna acción. Pero en el caso muy raro de que su aplicación necesite carga automática mientras se ejecuta en producción, establezca Rails.application.config.enable_dependency_loading
en true.
8.7 Serialización XML
ActiveModel::Serializers::Xml
se ha extraído de Rails a la gema activemodel-serializers-xml
. Para seguir utilizando la serialización XML en su aplicación, agregue gem 'activemodel-serializers-xml'
a su Gemfile
.
8.8 Se eliminó el soporte para el 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 una gema separada cuando encontremos a alguien que la mantenga.
8.9 Se eliminó el soporte para el depurador
debugger
no es compatible con Ruby 2.2, que es requerido por Rails 5. Use byebug
en su lugar.
8.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. En general, estos cambios son paralelos a 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.
8.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, no necesitará realizar ningún cambio. Si está utilizando map
y otros métodos que dependen de poder leer el hash independientemente de permitted?
, deberá actualizar su aplicación para primero permitir y luego convertirlo en un hash.
params.permit([:proceed_to, :return_to]).to_h
8.12 protect_from_forgery
ahora tiene prepend: false
como valor predeterminado
protect_from_forgery
ahora tiene prepend: false
como valor predeterminado, lo que significa que se insertará en la cadena de llamadas en el punto en el 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
.
8.13 El controlador de plantillas predeterminado ahora es RAW
Los archivos sin un controlador de plantillas en su extensión se renderizarán utilizando el controlador raw. Anteriormente, Rails renderizaba los archivos utilizando el controlador de plantillas ERB.
Si no desea que su archivo se maneje a través del controlador raw, debe agregar una extensión a su archivo que pueda ser analizada por el controlador de plantillas correspondiente.
8.14 Se agregó la coincidencia de comodines para las dependencias de plantillas
Ahora puede usar la coincidencia de comodines para las dependencias de sus plantillas. Por ejemplo, si estaba definiendo sus plantillas de la siguiente manera:
<% # Dependencia de plantilla: recordings/threads/events/subscribers_changed %>
<% # Dependencia de plantilla: recordings/threads/events/completed %>
<% # Dependencia de plantilla: recordings/threads/events/uncompleted %>
Ahora solo puede llamar a la dependencia una vez con un comodín.
<% # Dependencia de plantilla: recordings/threads/events/* %>
8.15 ActionView::Helpers::RecordTagHelper
se movió a la gema externa (record_tag_helper)
content_tag_for
y div_for
se han eliminado a favor de simplemente usar content_tag
. Para seguir utilizando los métodos antiguos, agregue la gema record_tag_helper
a su Gemfile
:
gem 'record_tag_helper', '~> 1.0'
Ver #18411 para más detalles.
8.16 Se eliminó el soporte para la gema protected_attributes
La gema protected_attributes
ya no es compatible con Rails 5.
8.17 Se eliminó el soporte para la gema activerecord-deprecated_finders
La gema activerecord-deprecated_finders
ya no es compatible con Rails 5.
8.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 volver a establecerlo en :sorted
.
# config/environments/test.rb
Rails.application.configure do
config.active_support.test_order = :sorted
end
8.19 ActionController::Live
se convirtió en un Concern
Si incluye ActionController::Live
en otro módulo que se incluye en su controlador, 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: ```ruby
Esta es una solución alternativa para controladores en streaming que realizan autenticación con Warden/Devise.
Ver https://github.com/plataformatec/devise/issues/2332
Autenticar en el enrutador es otra solución como se sugiere en ese problema.
class StreamingSupport include ActionController::Live # esto no funcionará en producción para Rails 5 # extend ActiveSupport::Concern # a menos que descomentes esta línea.
def process(name) super(name) rescue ArgumentError => e if e.message == 'uncaught throw :warden' throw :warden else raise e end end end ```
8.20 Nuevas configuraciones predeterminadas del framework
8.20.1 Opción belongs_to
requerida por defecto en Active Record
belongs_to
ahora generará un error de validación de forma predeterminada si la asociación no está presente.
Esto se puede desactivar por asociación con optional: true
.
Esta configuración predeterminada se configurará automáticamente en nuevas aplicaciones. Si una aplicación existente desea agregar esta característica, deberá activarla en un inicializador:
config.active_record.belongs_to_required_by_default = true
La configuración es global de forma predeterminada para todos tus modelos, pero puedes anularla en cada modelo. Esto te ayudará a migrar todos tus modelos para que tengan sus asociaciones requeridas de forma predeterminada.
class Book < ApplicationRecord
# el modelo aún no está listo para tener su asociación requerida de forma predeterminada
self.belongs_to_required_by_default = false
belongs_to(:author)
end
class Car < ApplicationRecord
# el modelo está listo para tener su asociación requerida de forma predeterminada
self.belongs_to_required_by_default = true
belongs_to(:pilot)
end
8.20.2 Tokens CSRF por formulario
Rails 5 ahora admite tokens CSRF por formulario para mitigar ataques de inyección de código en formularios creados por JavaScript. Con esta opción activada, cada formulario en tu aplicación tendrá su propio token CSRF específico para la acción y el método de ese formulario.
config.action_controller.per_form_csrf_tokens = true
8.20.3 Protección contra falsificaciones con verificación de origen
Ahora puedes configurar tu aplicación para verificar si el encabezado HTTP Origin
debe ser verificado
contra el origen del sitio como una defensa CSRF adicional. Establece lo siguiente en tu configuración para
activarlo:
config.action_controller.forgery_protection_origin_check = true
8.20.4 Permitir la configuración del nombre de la cola de Action Mailer
El nombre predeterminado de la cola de correo es mailers
. Esta opción de configuración te permite cambiar globalmente
el nombre de la cola. Establece lo siguiente en tu configuración:
config.action_mailer.deliver_later_queue_name = :new_queue_name
8.20.5 Soporte para fragmentos en caché en las vistas de Action Mailer
Establece config.action_mailer.perform_caching
en tu configuración para determinar si las vistas de Action Mailer
deben admitir el almacenamiento en caché.
config.action_mailer.perform_caching = true
8.20.6 Configurar la salida de db:structure:dump
Si estás utilizando schema_search_path
u otras extensiones de PostgreSQL, puedes controlar cómo se vuelca el esquema.
Establece :all
para generar todos los volcados, o :schema_search_path
para generar desde el esquema de búsqueda de esquemas.
config.active_record.dump_schemas = :all
8.20.7 Configurar opciones SSL para habilitar HSTS con subdominios
Establece lo siguiente en tu configuración para habilitar HSTS cuando se usen subdominios:
config.ssl_options = { hsts: { subdomains: true } }
8.20.8 Preservar la zona horaria del receptor
Cuando uses Ruby 2.4, puedes preservar la zona horaria del receptor al llamar a to_time
.
ActiveSupport.to_time_preserves_timezone = false
8.21 Cambios en la serialización JSON/JSONB
En Rails 5.0, la forma en que se serializan y deserializan los atributos JSON/JSONB ha cambiado. Ahora, si
asignas una columna igual a una String
, Active Record ya no convertirá esa cadena
en un Hash
, y en su lugar solo devolverá la cadena. Esto no se limita al código
que interactúa con modelos, sino que también afecta a la configuración de columna :default
en db/schema.rb
.
Se recomienda no asignar columnas igual a una String
, sino pasar un Hash
en su lugar, que se convertirá automáticamente en una cadena JSON y viceversa.
9 Actualización de Rails 4.1 a Rails 4.2
9.1 Consola web
Primero, agrega gem 'web-console', '~> 2.0'
al grupo :development
en tu Gemfile
y ejecuta bundle install
(no se incluirá cuando actualices Rails). Una vez instalado, simplemente puedes agregar una referencia al ayudante de la consola (es decir, <%= console %>
) en cualquier vista en la que desees habilitarlo. También se proporcionará una consola en cualquier página de error que veas en tu entorno de desarrollo.
9.2 Responders
respond_with
y los métodos respond_to
a nivel de clase se han extraído a la gema responders
. Para usarlos, simplemente agrega gem 'responders', '~> 2.0'
a tu Gemfile
. Las llamadas a respond_with
y respond_to
(nuevamente, a nivel de clase) ya no funcionarán sin haber incluido la gema responders
en tus dependencias.
```ruby
app/controllers/users_controller.rb
class UsersController < ApplicationController respond_to :html, :json
def show @user = User.find(params[:id]) respond_with @user end end ```
La instancia de respond_to
no se ve afectada y no requiere la gema adicional:
# app/controllers/users_controller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
respond_to do |format|
format.html
format.json { render json: @user }
end
end
end
Ver #16526 para más detalles.
9.3 Manejo de errores en callbacks de transacciones
Actualmente, Active Record suprime los errores generados dentro de los callbacks after_rollback
o after_commit
y solo los imprime en los registros. En la próxima versión, estos errores ya no se suprimirán. En su lugar, los errores se propagarán normalmente como en otros callbacks de Active Record.
Cuando defines un callback after_rollback
o after_commit
, recibirás una advertencia de deprecación sobre este cambio próximo. Cuando estés listo, puedes optar por el nuevo comportamiento y eliminar la advertencia de deprecación agregando la siguiente configuración a tu config/application.rb
:
config.active_record.raise_in_transactional_callbacks = true
Ver #14488 y #16537 para más detalles.
9.4 Orden de los casos de prueba
En Rails 5.0, los casos de prueba se ejecutarán en orden aleatorio de forma predeterminada. En anticipación a este cambio, Rails 4.2 introdujo una nueva opción de configuración active_support.test_order
para especificar explícitamente el orden de las pruebas. Esto te permite bloquear el comportamiento actual estableciendo la opción en :sorted
, u optar por el comportamiento futuro estableciendo la opción en :random
.
Si no especificas un valor para esta opción, se emitirá una advertencia de deprecación. Para evitar esto, agrega la siguiente línea a tu entorno de prueba:
# config/environments/test.rb
Rails.application.configure do
config.active_support.test_order = :sorted # o `:random` si prefieres
end
9.5 Atributos serializados
Cuando usas un codificador personalizado (por ejemplo, serialize :metadata, JSON
), asignar nil
a un atributo serializado lo guardará en la base de datos como NULL
en lugar de pasar el valor nil
a través del codificador (por ejemplo, "null"
cuando se usa el codificador JSON
).
9.6 Nivel de registro en producción
En Rails 5, el nivel de registro predeterminado para el entorno de producción se cambiará a :debug
(en lugar de :info
). Para mantener el valor predeterminado actual, agrega la siguiente línea a tu production.rb
:
# Establece en `:info` para que coincida con el valor predeterminado actual, o establece en `:debug` para optar por el valor predeterminado futuro.
config.log_level = :info
9.7 after_bundle
en plantillas de Rails
Si tienes una plantilla de Rails que agrega todos los archivos al control de versiones, fallará al agregar los binstubs generados porque se ejecuta antes de Bundler:
# template.rb
generate(:scaffold, "person name:string")
route "root to: 'people#index'"
rake("db:migrate")
git :init
git add: "."
git commit: %Q{ -m 'Initial commit' }
Ahora puedes envolver las llamadas git
en un bloque after_bundle
. Se ejecutará después de que se hayan generado los binstubs.
# template.rb
generate(:scaffold, "person name:string")
route "root to: 'people#index'"
rake("db:migrate")
after_bundle do
git :init
git add: "."
git commit: %Q{ -m 'Initial commit' }
end
9.8 Sanitizador HTML de Rails
Hay una nueva opción para sanitizar fragmentos de HTML en tus aplicaciones. El enfoque antiguo de html-scanner ahora está oficialmente en desuso a favor de Rails HTML Sanitizer
.
Esto significa que los métodos sanitize
, sanitize_css
, strip_tags
y strip_links
están respaldados por una nueva implementación.
Este nuevo sanitizador utiliza Loofah internamente. Loofah, a su vez, utiliza Nokogiri, que envuelve analizadores XML escritos en C y Java, por lo que la sanitización debería ser más rápida sin importar qué versión de Ruby uses.
La nueva versión actualiza sanitize
, por lo que puede recibir un Loofah::Scrubber
para una limpieza potente.
Consulta algunos ejemplos de scrubbers aquí.
También se han agregado dos nuevos scrubbers: PermitScrubber
y TargetScrubber
.
Lee el readme de la gema para obtener más información.
La documentación de PermitScrubber
y TargetScrubber
explica cómo puedes tener un control completo sobre cuándo y cómo se deben eliminar los elementos.
Si tu aplicación necesita usar la implementación antigua del sanitizador, incluye rails-deprecated_sanitizer
en tu Gemfile
:
gem 'rails-deprecated_sanitizer'
9.9 Pruebas DOM de Rails
El módulo TagAssertions
(que contiene métodos como assert_tag
), ha sido deprecado a favor de los métodos assert_select
del módulo SelectorAssertions
, que se ha extraído a la gema rails-dom-testing.
9.10 Tokens de autenticidad enmascarados
Para mitigar los ataques SSL, form_authenticity_token
ahora está enmascarado para que varíe con cada solicitud. Por lo tanto, los tokens se validan desenmascarando y luego descifrando. Como resultado, cualquier estrategia para verificar solicitudes de formularios no pertenecientes a Rails que dependa de un token CSRF de sesión estático debe tener esto en cuenta.
9.11 Action Mailer
Anteriormente, llamar a un método de mailer en una clase de mailer resultaba en la ejecución directa del método de instancia correspondiente. Con la introducción de Active Job y #deliver_later
, esto ya no es cierto. En Rails 4.2, la invocación de los métodos de instancia se pospone hasta que se llame a deliver_now
o deliver_later
. Por ejemplo:
class Notifier < ActionMailer::Base
def notify(user, ...)
puts "Llamado"
mail(to: user.email, ...)
end
end
mail = Notifier.notify(user, ...) # Notifier#notify aún no se ha llamado en este punto
mail = mail.deliver_now # Imprime "Llamado"
Esto no debería resultar en ninguna diferencia notable para la mayoría de las aplicaciones. Sin embargo, si necesitas que algunos métodos que no son de mailer se ejecuten de forma sincrónica y anteriormente confiabas en el comportamiento de proxy sincrónico, debes definirlos como métodos de clase en la clase de mailer directamente:
class Notifier < ActionMailer::Base
def self.broadcast_notifications(users, ...)
users.each { |user| Notifier.notify(user, ...) }
end
end
9.12 Soporte para claves foráneas
El DSL de migración se ha ampliado para admitir definiciones de claves foráneas. Si has estado utilizando la gema Foreigner, es posible que desees considerar eliminarla. Ten en cuenta que el soporte de claves foráneas de Rails es un subconjunto de Foreigner. Esto significa que no todas las definiciones de Foreigner pueden ser reemplazadas completamente por su contraparte DSL de migración de Rails.
El procedimiento de migración es el siguiente:
- Elimina
gem "foreigner"
del archivoGemfile
. - Ejecuta
bundle install
. - Ejecuta
bin/rake db:schema:dump
. - Asegúrate de que
db/schema.rb
contenga todas las definiciones de claves foráneas con las opciones necesarias.
10 Actualización de Rails 4.0 a Rails 4.1
10.1 Protección CSRF desde etiquetas <script>
remotas
O, "¡¿qué?! ¡mis pruebas están fallando!" o "¡mi widget <script>
está roto!"
La protección contra falsificación de solicitudes entre sitios (CSRF) ahora también cubre las solicitudes GET con respuestas JavaScript. Esto evita que un sitio de terceros haga referencia de forma remota a tu JavaScript con una etiqueta <script>
para extraer datos sensibles.
Esto significa que tus pruebas funcionales e de integración que usan
get :index, format: :js
ahora activarán la protección CSRF. Cambia a
xhr :get, :index, format: :js
para probar explícitamente una XmlHttpRequest
.
NOTA: Tus propias etiquetas <script>
también se tratan como de origen cruzado y se bloquean de forma predeterminada. Si realmente deseas cargar JavaScript desde etiquetas <script>
, ahora debes omitir explícitamente la protección CSRF en esas acciones.
10.2 Spring
Si deseas usar Spring como tu pre-cargador de aplicaciones, debes:
- Agregar
gem 'spring', group: :development
a tu archivoGemfile
. - Instalar Spring usando
bundle install
. - Generar el binstub de Spring con
bundle exec spring binstub
.
NOTA: Las tareas de rake definidas por el usuario se ejecutarán en el entorno development
de forma predeterminada. Si deseas que se ejecuten en otros entornos, consulta el README de Spring.
10.3 config/secrets.yml
Si deseas utilizar la nueva convención secrets.yml
para almacenar los secretos de tu aplicación, debes:
Crear un archivo
secrets.yml
en tu carpetaconfig
con el siguiente contenido:development: secret_key_base: test: secret_key_base: production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Utiliza tu
secret_key_base
existente del inicializadorsecret_token.rb
para establecer la variable de entornoSECRET_KEY_BASE
para los usuarios que ejecutan la aplicación Rails en producción. Alternativamente, simplemente puedes copiar elsecret_key_base
existente del inicializadorsecret_token.rb
asecrets.yml
en la secciónproduction
, reemplazando<%= ENV["SECRET_KEY_BASE"] %>
.Elimina el inicializador
secret_token.rb
.Utiliza
rake secret
para generar nuevas claves para las seccionesdevelopment
ytest
.Reinicia tu servidor.
10.4 Cambios en el helper de pruebas
Si tu helper de pruebas contiene una llamada a ActiveRecord::Migration.check_pending!
, esto se puede eliminar. La verificación ahora se realiza automáticamente cuando se requiere "rails/test_help", aunque dejar esta línea en tu helper no causa ningún daño de ninguna manera.
10.5 Serializador de cookies
Las aplicaciones creadas antes de Rails 4.1 utilizan Marshal
para serializar los valores de las cookies en los frascos de cookies firmadas y encriptadas. Si deseas utilizar el nuevo formato basado en JSON
en tu aplicación, puedes agregar un archivo inicializador con el siguiente contenido:
Rails.application.config.action_dispatch.cookies_serializer = :hybrid
Esto migrará automáticamente tus cookies serializadas con Marshal
al nuevo formato basado en JSON
.
Cuando uses el serializador :json
o :hybrid
, debes tener en cuenta que no todos los objetos de Ruby se pueden serializar como JSON. Por ejemplo, los objetos Date
y Time
se serializarán como cadenas, y las claves de los Hash
se convertirán en cadenas.
class CookiesController < ApplicationController
def set_cookie
cookies.encrypted[:expiration_date] = Date.tomorrow # => Thu, 20 Mar 2014
redirect_to action: 'read_cookie'
end
def read_cookie
cookies.encrypted[:expiration_date] # => "2014-03-20"
end
end
Es recomendable que solo almacenes datos simples (cadenas y números) en cookies. Si tienes que almacenar objetos complejos, tendrás que manejar la conversión manualmente al leer los valores en solicitudes posteriores.
Si utilizas el almacenamiento de sesión en cookies, esto también se aplicará a los hash session
y flash
.
10.6 Cambios en la estructura de Flash
Las claves de los mensajes Flash se normalizan a cadenas. Todavía se pueden acceder utilizando símbolos o cadenas. Al recorrer el flash siempre se obtendrán claves de cadena:
flash["cadena"] = "una cadena"
flash[:simbolo] = "un símbolo"
# Rails < 4.1
flash.keys # => ["cadena", :simbolo]
# Rails >= 4.1
flash.keys # => ["cadena", "simbolo"]
Asegúrate de comparar las claves de los mensajes Flash con cadenas.
10.7 Cambios en el manejo de JSON
Hay algunos cambios importantes relacionados con el manejo de JSON en Rails 4.1.
10.7.1 Eliminación de MultiJSON
MultiJSON ha llegado a su fin de vida y ha sido eliminado de Rails.
Si tu aplicación depende actualmente de MultiJSON directamente, tienes algunas opciones:
Agrega 'multi_json' a tu
Gemfile
. Ten en cuenta que esto podría dejar de funcionar en el futuro.Migra lejos de MultiJSON utilizando
obj.to_json
yJSON.parse(str)
en su lugar.
ADVERTENCIA: No reemplaces simplemente MultiJson.dump
y MultiJson.load
con
JSON.dump
y JSON.load
. Estas APIs de la gema JSON están destinadas a serializar y
deserializar objetos Ruby arbitrarios y generalmente no son seguras.
10.7.2 Compatibilidad con la gema JSON
Históricamente, Rails tenía algunos problemas de compatibilidad con la gema JSON. Usar
JSON.generate
y JSON.dump
dentro de una aplicación Rails podía producir
errores inesperados.
Rails 4.1 solucionó estos problemas aislando su propio codificador de la gema JSON. Las APIs de la gema JSON funcionarán normalmente, pero no tendrán acceso a ninguna característica específica de Rails. Por ejemplo:
class FooBar
def as_json(options = nil)
{ foo: 'bar' }
end
end
irb> FooBar.new.to_json
=> "{\"foo\":\"bar\"}"
irb> JSON.generate(FooBar.new, quirks_mode: true)
=> "\"#<FooBar:0x007fa80a481610>\""
10.7.3 Nuevo codificador JSON
El codificador JSON en Rails 4.1 ha sido reescrito para aprovechar la gema JSON. Para la mayoría de las aplicaciones, este cambio debería ser transparente. Sin embargo, como parte de la reescritura, se han eliminado las siguientes características del codificador:
- Detección de estructuras de datos circulares.
- Soporte para el gancho
encode_json
. - Opción para codificar objetos
BigDecimal
como números en lugar de cadenas.
Si tu aplicación depende de una de estas características, puedes recuperarlas
agregando la gema activesupport-json_encoder
a tu Gemfile
.
10.7.4 Representación JSON de objetos Time
#as_json
para objetos con componente de tiempo (Time
, DateTime
, ActiveSupport::TimeWithZone
)
ahora devuelve precisión en milisegundos de forma predeterminada. Si necesitas mantener el comportamiento anterior sin precisión en milisegundos,
configura lo siguiente en un inicializador:
ActiveSupport::JSON::Encoding.time_precision = 0
10.8 Uso de return
dentro de bloques de devolución de llamada en línea
Anteriormente, Rails permitía que los bloques de devolución de llamada en línea usaran return
de esta manera:
class ReadOnlyModel < ActiveRecord::Base
before_save { return false } # MAL
end
Este comportamiento nunca fue admitido intencionalmente. Debido a un cambio en las partes internas
de ActiveSupport::Callbacks
, esto ya no está permitido en Rails 4.1. Usar una
instrucción return
en un bloque de devolución de llamada en línea provoca que se genere un LocalJumpError
cuando se ejecuta la devolución de llamada.
Los bloques de devolución de llamada en línea que usan return
se pueden refactorizar para evaluar el
valor devuelto:
class ReadOnlyModel < ActiveRecord::Base
before_save { false } # BIEN
end
Alternativamente, si se prefiere return
, se recomienda definir explícitamente
un método:
class ReadOnlyModel < ActiveRecord::Base
before_save :before_save_callback # BIEN
private
def before_save_callback
false
end
end
Este cambio se aplica a la mayoría de los lugares en Rails donde se utilizan devoluciones de llamada, incluyendo
devoluciones de llamada de Active Record y Active Model, así como filtros en Action
Controller (por ejemplo, before_action
).
Consulta esta solicitud de extracción para obtener más detalles.
10.9 Métodos definidos en fixtures de Active Record
Rails 4.1 evalúa el ERB de cada fixture en un contexto separado, por lo que los métodos auxiliares definidos en una fixture no estarán disponibles en otras fixtures.
Los métodos auxiliares que se utilizan en varias fixtures deben definirse en módulos
incluidos en la nueva clase de contexto ActiveRecord::FixtureSet.context_class
, en
test_helper.rb
.
module FixtureFileHelpers
def file_sha(path)
OpenSSL::Digest::SHA256.hexdigest(File.read(Rails.root.join('test/fixtures', path)))
end
end
ActiveRecord::FixtureSet.context_class.include FixtureFileHelpers
10.10 I18n obliga a utilizar locales disponibles
Rails 4.1 ahora establece por defecto la opción de I18n enforce_available_locales
en true
. Esto
significa que se asegurará de que todos los locales pasados a él deben declararse en
la lista available_locales
.
Para desactivarlo (y permitir que I18n acepte cualquier opción de localización), agregue la siguiente configuración a su aplicación:
config.i18n.enforce_available_locales = false
Tenga en cuenta que esta opción se agregó como medida de seguridad, para garantizar que la entrada del usuario no se pueda utilizar como información de localización a menos que se conozca previamente. Por lo tanto, se recomienda no desactivar esta opción a menos que tenga una razón sólida para hacerlo.
10.11 Métodos mutadores llamados en Relation
Relation
ya no tiene métodos mutadores como #map!
y #delete_if
. Conviértalo en un Array
llamando a #to_a
antes de usar estos métodos.
Esto pretende evitar errores extraños y confusión en el código que llama directamente a los métodos mutadores en la Relation
.
# En lugar de esto
Author.where(name: 'Hank Moody').compact!
# Ahora tienes que hacer esto
authors = Author.where(name: 'Hank Moody').to_a
authors.compact!
10.12 Cambios en los alcances predeterminados
Los alcances predeterminados ya no se anulan por condiciones encadenadas.
En versiones anteriores, cuando definías un default_scope
en un modelo, se anulaba por condiciones encadenadas en el mismo campo. Ahora se fusiona como cualquier otro alcance.
Antes:
class User < ActiveRecord::Base
default_scope { where state: 'pending' }
scope :active, -> { where state: 'active' }
scope :inactive, -> { where state: 'inactive' }
end
User.all
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
User.active
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
User.where(state: 'inactive')
# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
Después:
class User < ActiveRecord::Base
default_scope { where state: 'pending' }
scope :active, -> { where state: 'active' }
scope :inactive, -> { where state: 'inactive' }
end
User.all
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
User.active
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'active'
User.where(state: 'inactive')
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending' AND "users"."state" = 'inactive'
Para obtener el comportamiento anterior, es necesario eliminar explícitamente la condición del default_scope
utilizando unscoped
, unscope
, rewhere
o except
.
class User < ActiveRecord::Base
default_scope { where state: 'pending' }
scope :active, -> { unscope(where: :state).where(state: 'active') }
scope :inactive, -> { rewhere state: 'inactive' }
end
User.all
# SELECT "users".* FROM "users" WHERE "users"."state" = 'pending'
User.active
# SELECT "users".* FROM "users" WHERE "users"."state" = 'active'
User.inactive
# SELECT "users".* FROM "users" WHERE "users"."state" = 'inactive'
10.13 Renderización de contenido desde una cadena
Rails 4.1 introduce las opciones :plain
, :html
y :body
para render
. Estas opciones son ahora la forma preferida de renderizar contenido basado en cadenas, ya que te permite especificar el tipo de contenido que deseas que se envíe en la respuesta.
render :plain
establecerá el tipo de contenido comotext/plain
render :html
establecerá el tipo de contenido comotext/html
render :body
no establecerá la cabecera del tipo de contenido.
Desde el punto de vista de la seguridad, si no esperas tener ningún marcado en el cuerpo de tu respuesta, debes usar render :plain
, ya que la mayoría de los navegadores escaparán el contenido inseguro en la respuesta por ti.
Estaremos desaconsejando el uso de render :text
en una versión futura. Así que por favor comienza a usar las opciones más precisas :plain
, :html
y :body
en su lugar. El uso de render :text
puede representar un riesgo de seguridad, ya que el contenido se envía como text/html
.
10.14 Tipos de datos JSON y hstore de PostgreSQL
Rails 4.1 mapeará las columnas json
y hstore
a un Hash
de Ruby con claves de cadena. En versiones anteriores, se utilizaba un HashWithIndifferentAccess
. Esto significa que el acceso mediante símbolos ya no es compatible. Esto también se aplica a los store_accessors
basados en columnas json
o hstore
. Asegúrate de usar claves de cadena de manera consistente.
10.15 Uso explícito de bloque para ActiveSupport::Callbacks
Rails 4.1 ahora espera que se pase un bloque explícito al llamar a ActiveSupport::Callbacks.set_callback
. Este cambio se deriva de la reescritura de ActiveSupport::Callbacks
para la versión 4.1.
# Anteriormente en Rails 4.0
set_callback :save, :around, ->(r, &block) { stuff; result = block.call; stuff }
# Ahora en Rails 4.1
set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff }
11 Actualización de Rails 3.2 a Rails 4.0
Si su aplicación se encuentra actualmente en una versión de Rails anterior a 3.2.x, debe actualizar a Rails 3.2 antes de intentar actualizar a Rails 4.0.
Los siguientes cambios están destinados a la actualización de su aplicación a Rails 4.0.
11.1 HTTP PATCH
Rails 4 ahora utiliza PATCH
como el verbo HTTP principal para las actualizaciones cuando se declara un recurso RESTful en config/routes.rb
. La acción update
todavía se utiliza y las solicitudes PUT
seguirán siendo enrutadas a la acción update
también. Entonces, si solo estás utilizando las rutas RESTful estándar, no es necesario hacer cambios:
resources :users
<%= form_for @user do |f| %>
class UsersController < ApplicationController
def update
# No se necesita ningún cambio; se preferirá PATCH y PUT seguirá funcionando.
end
end
Sin embargo, necesitarás hacer un cambio si estás utilizando form_for
para actualizar un recurso en conjunto con una ruta personalizada que utiliza el método HTTP PUT
:
resources :users do
put :update_name, on: :member
end
<%= form_for [ :update_name, @user ] do |f| %>
class UsersController < ApplicationController
def update_name
# Se necesita un cambio; form_for intentará utilizar una ruta PATCH que no existe.
end
end
Si la acción no se utiliza en una API pública y tienes libertad para cambiar el método HTTP, puedes actualizar tu ruta para utilizar patch
en lugar de put
:
resources :users do
patch :update_name, on: :member
end
Las solicitudes PUT
a /users/:id
en Rails 4 se enrutará a update
como lo hacen actualmente. Entonces, si tienes una API que recibe solicitudes PUT reales, seguirá funcionando. El enrutador también enrutará las solicitudes PATCH
a /users/:id
a la acción update
.
Si la acción se utiliza en una API pública y no puedes cambiar el método HTTP que se está utilizando, puedes actualizar tu formulario para utilizar el método PUT
en su lugar:
<%= form_for [ :update_name, @user ], method: :put do |f| %>
Para obtener más información sobre PATCH y por qué se realizó este cambio, consulta esta publicación en el blog de Rails.
11.1.1 Una nota sobre los tipos de medios
Las correcciones para el verbo PATCH
especifican que se debe utilizar un tipo de medio 'diff' con PATCH
. Uno de esos formatos es JSON Patch. Aunque Rails no admite nativamente JSON Patch, es bastante fácil agregar soporte:
# en tu controlador:
def update
respond_to do |format|
format.json do
# realizar una actualización parcial
@article.update params[:article]
end
format.json_patch do
# realizar un cambio sofisticado
end
end
end
# config/initializers/json_patch.rb
Mime::Type.register 'application/json-patch+json', :json_patch
Como JSON Patch se convirtió en un RFC recientemente, todavía no hay muchas bibliotecas Ruby excelentes. hana de Aaron Patterson es una de esas gemas, pero no tiene soporte completo para los últimos cambios en la especificación.
11.2 Gemfile
Rails 4.0 eliminó el grupo assets
de Gemfile
. Debes eliminar esa línea de tu Gemfile
al actualizar. También debes actualizar tu archivo de aplicación (en config/application.rb
):
# Requiere las gemas enumeradas en Gemfile, incluyendo cualquier gema
# que hayas limitado a :test, :development o :production.
Bundler.require(*Rails.groups)
11.3 vendor/plugins
Rails 4.0 ya no admite cargar complementos desde vendor/plugins
. Debes reemplazar cualquier complemento extrayéndolos a gemas y agregándolos a tu Gemfile
. Si decides no convertirlos en gemas, puedes moverlos a, por ejemplo, lib/my_plugin/*
y agregar un inicializador adecuado en config/initializers/my_plugin.rb
.
11.4 Active Record
Rails 4.0 ha eliminado el mapa de identidad de Active Record debido a algunas inconsistencias con las asociaciones. Si lo has habilitado manualmente en tu aplicación, deberás eliminar la siguiente configuración que ya no tiene efecto:
config.active_record.identity_map
.El método
delete
en las asociaciones de colecciones ahora puede recibir argumentosInteger
oString
como identificadores de registros, además de registros, al igual que el métododestroy
. Anteriormente, esto generaba un errorActiveRecord::AssociationTypeMismatch
para tales argumentos. A partir de Rails 4.0,delete
intentará automáticamente encontrar los registros que coincidan con los identificadores dados antes de eliminarlos.En Rails 4.0, cuando se cambia el nombre de una columna o una tabla, los índices relacionados también se renombran. Si tienes migraciones que renombran los índices, ya no son necesarios.
Rails 4.0 ha cambiado
serialized_attributes
yattr_readonly
para que sean solo métodos de clase. No debes utilizar métodos de instancia ya que ahora están en desuso. Debes cambiarlos para que utilicen métodos de clase, por ejemplo, cambiarself.serialized_attributes
aself.class.serialized_attributes
.Cuando se utiliza el codificador predeterminado, asignar
nil
a un atributo serializado lo guardará en la base de datos comoNULL
en lugar de pasar el valornil
a través de YAML ("--- \n...\n"
).Rails 4.0 ha eliminado la función
attr_accessible
yattr_protected
a favor de Strong Parameters. Puedes usar la gema Protected Attributes para una actualización sin problemas.Si no estás utilizando Protected Attributes, puedes eliminar cualquier opción relacionada con esta gema, como
whitelist_attributes
omass_assignment_sanitizer
.Rails 4.0 requiere que los scopes utilicen un objeto callable como un Proc o lambda:
scope :active, where(active: true) # se convierte en scope :active, -> { where active: true }
Rails 4.0 ha deprecado
ActiveRecord::Fixtures
a favor deActiveRecord::FixtureSet
.Rails 4.0 ha deprecado
ActiveRecord::TestCase
a favor deActiveSupport::TestCase
.Rails 4.0 ha deprecado la API de búsqueda basada en hash de estilo antiguo. Esto significa que los métodos que anteriormente aceptaban "opciones de búsqueda" ya no lo hacen. Por ejemplo,
Book.find(:all, conditions: { name: '1984' })
ha sido deprecado a favor deBook.where(name: '1984')
.Todos los métodos dinámicos excepto
find_by_...
yfind_by_...!
han sido deprecados. Así es como puedes manejar los cambios:find_all_by_...
se convierte enwhere(...)
.find_last_by_...
se convierte enwhere(...).last
.scoped_by_...
se convierte enwhere(...)
.find_or_initialize_by_...
se convierte enfind_or_initialize_by(...)
.find_or_create_by_...
se convierte enfind_or_create_by(...)
.
Ten en cuenta que
where(...)
devuelve una relación, no un array como los antiguos finders. Si necesitas unArray
, utilizawhere(...).to_a
.Estos métodos equivalentes pueden no ejecutar el mismo SQL que la implementación anterior.
Para volver a habilitar los antiguos finders, puedes utilizar la gema activerecord-deprecated_finders.
Rails 4.0 ha cambiado la tabla de unión predeterminada para las relaciones
has_and_belongs_to_many
para eliminar el prefijo común del nombre de la segunda tabla. Cualquier relaciónhas_and_belongs_to_many
existente entre modelos con un prefijo común debe especificarse con la opciónjoin_table
. Por ejemplo:CatalogCategory < ActiveRecord::Base has_and_belongs_to_many :catalog_products, join_table: 'catalog_categories_catalog_products' end CatalogProduct < ActiveRecord::Base has_and_belongs_to_many :catalog_categories, join_table: 'catalog_categories_catalog_products' end
Ten en cuenta que el prefijo también tiene en cuenta los scopes, por lo que las relaciones entre
Catalog::Category
yCatalog::Product
oCatalog::Category
yCatalogProduct
deben actualizarse de manera similar.
11.5 Active Resource
Rails 4.0 extrajo Active Resource a su propia gema. Si aún necesitas esta característica, puedes agregar la gema Active Resource en tu Gemfile
.
11.6 Active Model
Rails 4.0 ha cambiado cómo se adjuntan los errores con
ActiveModel::Validations::ConfirmationValidator
. Ahora, cuando las validaciones de confirmación fallan, el error se adjuntará a:#{attribute}_confirmation
en lugar deattribute
.Rails 4.0 ha cambiado el valor predeterminado de
ActiveModel::Serializers::JSON.include_root_in_json
afalse
. Ahora, Active Model Serializers y los objetos Active Record tienen el mismo comportamiento predeterminado. Esto significa que puedes comentar o eliminar la siguiente opción en el archivoconfig/initializers/wrap_parameters.rb
:# Disable root element in JSON by default. # ActiveSupport.on_load(:active_record) do # self.include_root_in_json = false # end
11.7 Action Pack
Rails 4.0 introduce
ActiveSupport::KeyGenerator
y lo utiliza como base para generar y verificar cookies firmadas (entre otras cosas). Las cookies firmadas existentes generadas con Rails 3.x se actualizarán de forma transparente si dejas tusecret_token
existente en su lugar y agregas el nuevosecret_key_base
.# config/initializers/secret_token.rb Myapp::Application.config.secret_token = 'existing secret token' Myapp::Application.config.secret_key_base = 'new secret key base'
Ten en cuenta que debes esperar para configurar
secret_key_base
hasta que el 100% de tu base de usuarios esté en Rails 4.x y estés razonablemente seguro de que no necesitarás volver a Rails 3.x. Esto se debe a que las cookies firmadas basadas en el nuevosecret_key_base
en Rails 4.x no son compatibles con versiones anteriores de Rails 3.x. Puedes dejar tusecret_token
existente en su lugar, no configurar el nuevosecret_key_base
e ignorar las advertencias de deprecación hasta que estés razonablemente seguro de que tu actualización esté completa.Si dependes de la capacidad de que aplicaciones externas o JavaScript puedan leer las cookies de sesión firmadas de tu aplicación Rails (o cookies firmadas en general), no debes configurar
secret_key_base
hasta que hayas separado estas preocupaciones.Rails 4.0 encripta el contenido de las sesiones basadas en cookies si se ha configurado
secret_key_base
. Rails 3.x firmaba, pero no encriptaba, el contenido de las sesiones basadas en cookies. Las cookies firmadas son "seguras" en el sentido de que se verifica que hayan sido generadas por tu aplicación y son a prueba de manipulaciones. Sin embargo, los usuarios finales pueden ver el contenido y encriptar el contenido elimina esta advertencia/preocupación sin una penalización significativa en el rendimiento.Por favor, lee Pull Request #9978 para obtener detalles sobre el cambio a cookies de sesión encriptadas.
Rails 4.0 eliminó la opción
ActionController::Base.asset_path
. Utiliza la funcionalidad del pipeline de assets.Rails 4.0 ha deprecado la opción
ActionController::Base.page_cache_extension
. En su lugar, utilizaActionController::Base.default_static_extension
.Rails 4.0 ha eliminado el almacenamiento en caché de acciones y páginas de Action Pack. Deberás agregar la gema
actionpack-action_caching
para utilizarcaches_action
y la gemaactionpack-page_caching
para utilizarcaches_page
en tus controladores.Rails 4.0 ha eliminado el analizador de parámetros XML. Deberás agregar la gema
actionpack-xml_parser
si necesitas esta funcionalidad.Rails 4.0 cambia la búsqueda predeterminada de
layout
utilizando símbolos o procs que devuelven nil. Para obtener el comportamiento de "sin diseño", devuelve false en lugar de nil.Rails 4.0 cambia el cliente memcached predeterminado de
memcache-client
adalli
. Para actualizar, simplemente agregagem 'dalli'
a tuGemfile
.Rails 4.0 deprecia los métodos
dom_id
ydom_class
en controladores (son válidos en vistas). Deberás incluir el móduloActionView::RecordIdentifier
en los controladores que requieran esta funcionalidad.Rails 4.0 deprecia la opción
:confirm
para el helperlink_to
. En su lugar, debes utilizar un atributo de datos (por ejemplo,data: { confirm: '¿Estás seguro?' }
). Esta deprecación también afecta a los helpers basados en este (comolink_to_if
olink_to_unless
).Rails 4.0 cambió la forma en que funcionan
assert_generates
,assert_recognizes
yassert_routing
. Ahora todas estas aserciones lanzanAssertion
en lugar deActionController::RoutingError
.Rails 4.0 genera un
ArgumentError
si se definen rutas con nombres conflictivos. Esto puede ocurrir con rutas con nombres explícitamente definidos o con el métodoresources
. Aquí hay dos ejemplos que entran en conflicto con rutas llamadasexample_path
:get 'one' => 'test#example', as: :example get 'two' => 'test#example', as: :example
resources :examples get 'clashing/:id' => 'test#example', as: :example
En el primer caso, simplemente evita usar el mismo nombre para múltiples rutas. En el segundo caso, puedes utilizar las opciones
only
oexcept
proporcionadas por el métodoresources
para restringir las rutas creadas, como se detalla en la Guía de enrutamiento.Rails 4.0 también cambió la forma en que se dibujan las rutas de caracteres Unicode. Ahora puedes dibujar rutas de caracteres Unicode directamente. Si ya dibujas este tipo de rutas, debes cambiarlas, por ejemplo:
get Rack::Utils.escape('こんにちは'), controller: 'welcome', action: 'index'
se convierte en
get 'こんにちは', controller: 'welcome', action: 'index'
Rails 4.0 requiere que las rutas que utilizan
match
especifiquen el método de solicitud. Por ejemplo:# Rails 3.x match '/' => 'root#index' # se convierte en match '/' => 'root#index', via: :get # o get '/' => 'root#index'
Rails 4.0 ha eliminado el middleware
ActionDispatch::BestStandardsSupport
,<!DOCTYPE html>
ya activa el modo estándar según https://msdn.microsoft.com/en-us/library/jj676915(v=vs.85).aspx y el encabezado ChromeFrame se ha movido aconfig.action_dispatch.default_headers
.Recuerda que también debes eliminar cualquier referencia al middleware de tu código de aplicación, por ejemplo:
# Lanzar excepción config.middleware.insert_before(Rack::Lock, ActionDispatch::BestStandardsSupport)
También verifica la configuración de tu entorno para
config.action_dispatch.best_standards_support
y elimínala si está presente.Rails 4.0 permite la configuración de encabezados HTTP mediante
config.action_dispatch.default_headers
. Los valores predeterminados son los siguientes:config.action_dispatch.default_headers = { 'X-Frame-Options' => 'SAMEORIGIN', 'X-XSS-Protection' => '1; mode=block' }
Ten en cuenta que si tu aplicación depende de cargar ciertas páginas en un
<frame>
o<iframe>
, es posible que debas establecer explícitamenteX-Frame-Options
enALLOW-FROM ...
oALLOWALL
.En Rails 4.0, la precompilación de activos ya no copia automáticamente activos que no sean JS/CSS de
vendor/assets
ylib/assets
. Los desarrolladores de aplicaciones y motores de Rails deben colocar estos activos enapp/assets
o configurarconfig.assets.precompile
.En Rails 4.0, se lanza
ActionController::UnknownFormat
cuando la acción no maneja el formato de la solicitud. De forma predeterminada, la excepción se maneja respondiendo con un código 406 Not Acceptable, pero ahora puedes anular eso. En Rails 3, siempre se devolvía un código 406 Not Acceptable. No hay anulaciones.En Rails 4.0, se lanza una excepción genérica
ActionDispatch::ParamsParser::ParseError
cuandoParamsParser
no puede analizar los parámetros de la solicitud. Deberás rescatar esta excepción en lugar deMultiJson::DecodeError
a nivel bajo, por ejemplo.En Rails 4.0,
SCRIPT_NAME
se anida correctamente cuando los motores están montados en una aplicación que se sirve desde un prefijo de URL. Ya no es necesario establecerdefault_url_options[:script_name]
para solucionar los prefijos de URL sobrescritos.Rails 4.0 ha deprecado
ActionController::Integration
en favor deActionDispatch::Integration
.Rails 4.0 ha deprecado
ActionController::IntegrationTest
en favor deActionDispatch::IntegrationTest
.Rails 4.0 ha deprecado
ActionController::PerformanceTest
en favor deActionDispatch::PerformanceTest
.Rails 4.0 ha deprecado
ActionController::AbstractRequest
en favor deActionDispatch::Request
.Rails 4.0 ha deprecado
ActionController::Request
en favor deActionDispatch::Request
.Rails 4.0 ha deprecado
ActionController::AbstractResponse
en favor deActionDispatch::Response
.Rails 4.0 ha deprecado
ActionController::Response
en favor deActionDispatch::Response
.Rails 4.0 ha deprecado
ActionController::Routing
en favor deActionDispatch::Routing
.Active Support
Rails 4.0 elimina el alias j
para ERB::Util#json_escape
ya que j
ya se utiliza para ActionView::Helpers::JavaScriptHelper#escape_javascript
.
11.7.1 Caché
El método de caché ha cambiado entre Rails 3.x y 4.0. Debes cambiar el espacio de nombres de la caché y desplegar con una caché fría.
11.8 Orden de carga de los ayudantes
El orden en el que se cargan los ayudantes de más de un directorio ha cambiado en Rails 4.0. Anteriormente, se recopilaban y luego se ordenaban alfabéticamente. Después de actualizar a Rails 4.0, los ayudantes conservarán el orden de los directorios cargados y se ordenarán alfabéticamente solo dentro de cada directorio. A menos que utilices explícitamente el parámetro helpers_path
, este cambio solo afectará la forma de cargar los ayudantes de los motores. Si dependes del orden, debes verificar si los métodos correctos están disponibles después de la actualización. Si deseas cambiar el orden en que se cargan los motores, puedes usar el método config.railties_order=
.
11.9 Active Record Observer y Action Controller Sweeper
ActiveRecord::Observer
y ActionController::Caching::Sweeper
se han extraído a la gema rails-observers
. Deberás agregar la gema rails-observers
si necesitas estas características.
11.10 sprockets-rails
- Se han eliminado
assets:precompile:primary
yassets:precompile:all
. Utilizaassets:precompile
en su lugar. La opción
config.assets.compress
debe cambiarse aconfig.assets.js_compressor
de la siguiente manera, por ejemplo:config.assets.js_compressor = :uglifier
11.11 sass-rails
asset-url
con dos argumentos está en desuso. Por ejemplo:asset-url("rails.png", image)
se convierte enasset-url("rails.png")
.
12 Actualización de Rails 3.1 a Rails 3.2
Si tu aplicación se encuentra actualmente en una versión de Rails anterior a 3.1.x, debes actualizar a Rails 3.1 antes de intentar una actualización a Rails 3.2.
Los siguientes cambios están destinados a actualizar tu aplicación a la última versión 3.2.x de Rails.
12.1 Gemfile
Realiza los siguientes cambios en tu Gemfile
.
gem 'rails', '3.2.21'
group :assets do
gem 'sass-rails', '~> 3.2.6'
gem 'coffee-rails', '~> 3.2.2'
gem 'uglifier', '>= 1.0.3'
end
12.2 config/environments/development.rb
Hay algunas nuevas configuraciones que debes agregar a tu entorno de desarrollo:
# Levanta una excepción en la protección de asignación masiva para los modelos de Active Record
config.active_record.mass_assignment_sanitizer = :strict
# Registra el plan de consulta para las consultas que tardan más de esto (funciona
# con SQLite, MySQL y PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
12.3 config/environments/test.rb
La configuración mass_assignment_sanitizer
también debe agregarse a config/environments/test.rb
:
# Levanta una excepción en la protección de asignación masiva para los modelos de Active Record
config.active_record.mass_assignment_sanitizer = :strict
12.4 vendor/plugins
Rails 3.2 deprecia vendor/plugins
y Rails 4.0 los eliminará por completo. Si bien no es estrictamente necesario como parte de una actualización a Rails 3.2, puedes comenzar a reemplazar cualquier plugin extrayéndolos a gemas y agregándolos a tu Gemfile
. Si decides no convertirlos en gemas, puedes moverlos a, por ejemplo, lib/my_plugin/*
y agregar un inicializador apropiado en config/initializers/my_plugin.rb
.
12.5 Active Record
Se ha eliminado la opción :dependent => :restrict
de belongs_to
. Si deseas evitar eliminar el objeto si hay objetos asociados, puedes establecer :dependent => :destroy
y devolver false
después de verificar la existencia de la asociación desde cualquier callback de destrucción del objeto asociado.
13 Actualización de Rails 3.0 a Rails 3.1
Si tu aplicación se encuentra actualmente en una versión de Rails anterior a 3.0.x, debes actualizar a Rails 3.0 antes de intentar una actualización a Rails 3.1.
Los siguientes cambios están destinados a actualizar tu aplicación a Rails 3.1.12, la última versión 3.1.x de Rails.
13.1 Gemfile
Realiza los siguientes cambios en tu Gemfile
.
gem 'rails', '3.1.12'
gem 'mysql2'
# Necesario para el nuevo pipeline de activos
group :assets do
gem 'sass-rails', '~> 3.1.7'
gem 'coffee-rails', '~> 3.1.1'
gem 'uglifier', '>= 1.0.3'
end
# jQuery es la biblioteca de JavaScript predeterminada en Rails 3.1
gem 'jquery-rails'
13.2 config/application.rb
El pipeline de activos requiere las siguientes adiciones:
config.assets.enabled = true
config.assets.version = '1.0'
Si tu aplicación utiliza una ruta "/assets" para un recurso, es posible que desees cambiar el prefijo utilizado para los activos para evitar conflictos:
# Por defecto es '/assets'
config.assets.prefix = '/asset-files'
13.3 config/environments/development.rb
Elimina la configuración RJS config.action_view.debug_rjs = true
.
Agrega estas configuraciones si habilitas el pipeline de activos:
# No comprime los activos
config.assets.compress = false
# Expande las líneas que cargan los activos
config.assets.debug = true
13.4 config/environments/production.rb
Nuevamente, la mayoría de los cambios a continuación son para el pipeline de activos. Puedes leer más sobre esto en la guía Asset Pipeline. ```ruby
Comprimir JavaScripts y CSS
config.assets.compress = true
No volver a la canalización de activos si falta un activo precompilado
config.assets.compile = false
Generar resúmenes para las URL de los activos
config.assets.digest = true
Por defecto, Rails.root.join("public/assets")
config.assets.manifest = TU_RUTA
Precompilar activos adicionales (application.js, application.css y todos los que no sean JS/CSS ya están agregados)
config.assets.precompile += %w( admin.js admin.css )
Forzar todo el acceso a la aplicación a través de SSL, utilizar Strict-Transport-Security y utilizar cookies seguras.
config.force_ssl = true
### config/environments/test.rb
Puedes ayudar a probar el rendimiento con estas adiciones a tu entorno de prueba:
```ruby
# Configurar el servidor de activos estáticos para pruebas con Cache-Control para el rendimiento
config.public_file_server.enabled = true
config.public_file_server.headers = {
'Cache-Control' => 'public, max-age=3600'
}
13.5 config/initializers/wrap_parameters.rb
Agrega este archivo con el siguiente contenido, si deseas envolver los parámetros en un hash anidado. Esto está activado de forma predeterminada en las nuevas aplicaciones.
# Asegúrate de reiniciar tu servidor cuando modifiques este archivo.
# Este archivo contiene configuraciones para ActionController::ParamsWrapper que
# está habilitado de forma predeterminada.
# Habilitar envoltura de parámetros para JSON. Puedes deshabilitarlo configurando :format como un array vacío.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
# Deshabilitar el elemento raíz en JSON de forma predeterminada.
ActiveSupport.on_load(:active_record) do
self.include_root_in_json = false
end
13.6 config/initializers/session_store.rb
Necesitas cambiar la clave de tu sesión por algo nuevo, o eliminar todas las sesiones:
# en config/initializers/session_store.rb
AppName::Application.config.session_store :cookie_store, key: 'ALGONUEVO'
o
$ bin/rake db:sessions:clear
13.7 Elimina las opciones :cache y :concat en las referencias de los ayudantes de activos en las vistas
- Con el Pipeline de Activos, las opciones :cache y :concat ya no se utilizan, elimina estas opciones de tus vistas.
Comentarios
Se te anima a ayudar a mejorar la calidad de esta guía.
Por favor, contribuye si encuentras algún error tipográfico o factual. Para empezar, puedes leer nuestra contribución a la documentación sección.
También puedes encontrar contenido incompleto o desactualizado. Por favor, añade cualquier documentación faltante para main. Asegúrate de revisar Edge Guides primero para verificar si los problemas ya están resueltos o no en la rama principal. Consulta las Directrices de las Guías de Ruby on Rails para el estilo y las convenciones.
Si por alguna razón encuentras algo que corregir pero no puedes solucionarlo tú mismo, por favor abre un problema.
Y por último, cualquier tipo de discusión sobre la documentación de Ruby on Rails es muy bienvenida en el Foro oficial de Ruby on Rails.