Rails Upgrade
Actualización de Rails 6.1.7 a Rails 7.0 en una aplicación tipo API.
Antes de la actualización las especificaciones son:
- Tengo un Mac M1 MacOs ventura
- Rails 6.1.7
- Ruby 2.7.3
- Cliente para el mac PostgreSQL 13.0
- Redis server 6.2.4
Paso a paso de la actualización:
- Hay una recomendación respecto a no actualizar de una versión muy antigua a una muy reciente, por ejemplo, no es recomendable actualizar de Rails 5 a Rails 7, en este caso no aplica, ya que estamos pasando de 6.1 a 7 lo cual está bien.
- Copiar y pegar nuestro Gemfile.lock en RailsBumb para poder revisar cuáles de nuestras gemas nos van a generar errores o problemas.
- Usar la gema “next_rails” para revisar cuáles gemas tenemos que actualizar, cuando ya la tengamos instalada solo haremos un bundle_report compatibility --rails-version=version_deseada, después de esto ya podemos actualizar las gemas que nos aparezcan en el reporte.
- Actualización de gemas:
- Si el reporte nos pide actualizar gemas que hacen parte de Rails como ActionMaileroActionTextestas se van a actualizar con el cambio de versión a Rails 7. Si las gemas son instaladas por nosotros, obviamente debemos hacer la actualización.
- No es aconsejable tener una versión fija de una gema en nuestro Gemfileasí que es un buen momento para ir eliminando eso.
 
- Si el reporte nos pide actualizar gemas que hacen parte de Rails como 
- Luego de actualizar las gemas ahora podemos en nuestro Gemfileactualizar la versión de Rails y correrbundle update.
- Cuando se haga la actualización lo primero es cambiar el load_defaultsa Rails 7 en nuestro archivoconfig/application.rb.
- En mi caso uso Springesta gema está en su versión 2.1.1 por alguna razónnext-railsno la tuvo en cuenta, pero debe ser actualizada a una versión3X.- Cuando intenté actualizar la gema me decía que no podía porque estaba bloqueada, para esto lo que hice fue eliminar mi Gemfile.lock.
- Luego en config/environments/test.rblo dejé configurado enfalse.
 
- Configurar Zeitwerk.- 
Zeitwerkes la única forma en Rails 7 para cargar de forma segura archivos y evitar el uso excesivo derequire.
- Como ya se hizo el cambio a Rails 7 en la aplicación en config/application.rbse debe eliminar la líneaconfig.autoloader.
- Verificar si ya está corriendo todo bien con bin/rails runner 'p Rails.autoloaders.zeitwerk_enabled?'debe retornartrueo en su defecto los respectivos warnings.
 
- 
- Encriptación
- En este punto, al iniciar el server estaba obteniendo un error ActiveSupport::MessageEncryptor::InvalidMessageesto es por la encriptación.
- En la API se encripta los atributos siguiendo este tutorial, pero al actualizar Rails la encriptación cambia, porque Rails 7 usa SHA256 mientras que en las versiones anteriores se usa SHA1, pero este protocolo está obsoleto, para solucionar esto se debe especificar que siga encriptando con SHA1 mientras que luego se hace la el cambio para poder usar los atributos encriptados de Rails 7, para solucionarlo me funcionó agregar el hash_digest_classasí:
 
- En este punto, al iniciar el server estaba obteniendo un error 
class EncryptionService
  KEY = ActiveSupport::KeyGenerator.new(
    Rails.application.credentials[:secret_key_base],
    hash_digest_class: OpenSSL::Digest::SHA1
  ).generate_key(
    Rails.application.credentials[:ENCRYPTION_SERVICE_SALT],
    ActiveSupport::MessageEncryptor.key_len
  ).freeze
- Al correr los test encontré el error RuntimeError: Foreign key violations found in your fixture data, esto se debe a que en versiones anteriores se podían tenerfixturescon unamissing association, esto ya no será posible en Rails 7.- Una opción es en application.rbagregar la líneaconfig.active_record.verify_foreign_keys_for_fixtures = false.
- La otra opción es arreglar los errores en los fixtures(Lo cual es lo recomendado), para detectar qué tablas tenemos mal, primero reseteamos y cargamos la base datos de test para luego entrar en la consola así:
 
- Una opción es en 
RAILS_ENV=test bin/rails db:reset
RAILS_ENV=test bin/rails db:fixtures:load
RAILS_ENV=test bin/rails c 
- Luego corremos esta consulta para identificar si hay tablas que les falta una asociación para poder corregir los fixturesy ya con esto el error se solucionará:
ActiveRecord::Base.connection.execute(<<~SQL)
  do $$
    declare r record;
  BEGIN
  FOR r IN (
    SELECT FORMAT(
      'UPDATE pg_constraint SET convalidated=false WHERE conname = ''%I''; ALTER TABLE %I VALIDATE CONSTRAINT %I;',
      constraint_name,
      table_name,
      constraint_name
    ) AS constraint_check
    FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY'
  )
    LOOP
      EXECUTE (r.constraint_check);
    END LOOP;
  END;
  $$;
SQL
- El siguiente error a corregir fue ActionDispatch::Request::Session::DisabledSessionError: Your application has sessions disabled. To write to the session you must first configure a session store:- En config/application.rbtenía la líneaconfig.middleware.use ActionDispatch::Cookiespara solucionar me funcionó esta respuesta de este hilo
 
- En 
Este fue todo el proceso en mi caso, las guías y documentos de apoyo para esta actualización fueron:
 


 
    
Top comments (0)