Skip to content

2019_11 Actualización a Rails 6 en 6 pasos

Vladimir Támara Patiño edited this page Sep 3, 2020 · 1 revision

Si tu aplicación ya está en Rails 5.2.x, bastan los siguientes pasos:

  1. Comienza por cambiar en tu Gemfile la versión de rails por ejemplo por:

    gem 'rails', '~> 6.0.0'
    

    En el mismo archivo quita gemas que ya no se necesitan en Rails 6 (como minitest-rails-capybara que se explica más adelante), cambia aquellas que soportan Rails 6 en algúna rama o repositorio diferente (por ejemplo chosen-rails como se explica más adelante) hasta que funcione bien

    bundle update; bundle install
  2. Actualiza binarios y archivos de configuración, aunque antes es recomendable sacar copia de algunos archivos como config/application.rb, config/routes.rb, config/environment.rb, config/initializers/inflectors.rb y después ejecuta:

    bin/rails app:update

    Teniendo cuidado de mezclar los archivos en los que hayas hecho configuraciones adicionales y remplazando los que no. Si habías usado antes sdiff puedes facilitarte el proceso de mezclado de cada par de archivos para que queden en /tmp/s(y copiar a medida que queden bien) iniciando con THOR_MERGE="sdiff -o /tmp/s" bin/rails app:update. Este procedimiento dejará entre otros un archivo config/initializers/new_framework_defaults_6_0.rb en el que podrían deshabilitarse algunas características nuevas de Rails 6 --por omisión todas están habilitadas.

  3. La ejecución suele requerir que se establezca config.hosts, por ejemplo en config/application.rb agregando:

    config.hosts << ENV['CONFIG_HOSTS'] || '127.0.0.1'
    

    y ejecutando servidor de desarrollo con CONFIG_HOSTS=mi.servidor.org bin/rails s, pruebas con CONFIG_HOSTS=127.0.0.1 bin/rails test (algunas pruebas requieren CONFIG_HOSTS=www.example.com bin/rails test).

  4. Como en Rails 6 funcionan de manera nativa las pruebas al sistema (en adJ/OpenBSD con el controlador poltergeist y el navegador headless PhantomJS), si habías hecho pruebas con minitest-rails-capybara por ejemplo en el directorio test/integration muevelas a test/system y modificalas (como se explica más adelante) hasta que operen bien:

    bin/rails test
    CONFIG_HOSTS=127.0.0.1 bin/rails test:system
  5. Como webpacker es la herramienta por omisión para manejar Javascript en Rails 6 es bueno comenzar a configurarla, para eso:

    • Instala yarn para el usuario que lo usará (en ~/.yarn/bin) con:
      doas pkg_add install bash
      ftp -o- https://yarnpkg.com/install.sh | bash
      . $HOME/.profile
      después de esto sería posible instalar yarn de manera global (doas yarn global add yarn --prefix /usr/local) pero no es recomendado según documentación de yarn. Así que es mejor adaptar scripts de arranque en sitios de producción para que empleen el ambiente del usuario en el que se instaló yarn.
    • Agrega al archivo Gemfile la línea gem 'webpacker' y ejecuta bundle install
    • Desde el directorio donde puede correr la aplicación (/ en aplicaciones y test/dummy en motores) ejecutar:
      CXX=c++ bin/rails webpacker:install 
      Ten en cuenta que al empezar a usar webpacker con regularidad deberás ejecutar:
      CXX=c++ yarn upgrade 
      para actualizar dependencias javascript y
      CXX=c++ yarn install 
      para instalar dependencias javascript recientes.
  6. Agrega lo nuevo al repositorio git (excepto el contenido de node_modules).

Revisa otras sugerencias en: https://guides.rubyonrails.org/upgrading_ruby_on_rails.html

Si tienes problemas para actualizar tu aplicación que depende de sip a Rails 5, puedes dejarla temporalmente en Rails 5 empleando la rama rails5 de sip.

Anotaciones:

  • webpacker da más modularidad que la tubería de recursos (assets pipeline o sprockets) y no sólo permite manejar javascript sino otros recursos (como imagenes y hojas de estilo). Esto facilita separar aplicación de interfaz de aplicación al lado del servidor y tener a disposición los paquetes npm al lado de la interfaz (como react, vue y demás) así como las herramientas de javascript para manejarlas (como node.js, yarn y demás).
    En todo caso la tubería de recursos (assets pipeline) sigue operando en Rails 6 con todo lo que dejes en el directorio app/assets/. Para realmente usar webpacker puedes ir pasando y convirtiendo lo del directorio /app/assets/javascript a app/javascript (que por omisión es el directorio manejado por webpacker) así como ir remplazando gemas que sólo incluían javascript (como rails-jquery) o CSS (como bootstrap o font-awesome) por los paquetes npm manejados por yarn y webpacker. Si incluso deseas separar aún más interfaz de servidor, puedes renombrar app/javascript por ejemplo por app/interfaz e ir pasando hojas de estilo e imágenes. Ver detalles en https://medium.com/@coorasse/goodbye-sprockets-welcome-webpacker-3-0-ff877fb8fa79

  • La gema minitest-rails-capybara es incompatible con Rails 6 e innecesaria porque ya operan bien pruebas del sistema con Capybara, poltergeist y PhantomJS como está bien documentado en https://edgeguides.rubyonrails.org/testing.html (la gema webdrivers inicialmente no tiene soporte para OpenBSD). El cambio se resume en https://chriskottom.com/blog/2017/04/full-stack-testing-with-rails-system-tests/. Los cambios a las pruebas que hemos necesitado han sido pocos:

    1. El archivo tests/test_helper basta que sea:
      # encoding: utf-8
      
      ENV['RAILS_ENV'] ||= 'test'
      
      require 'simplecov'
      SimpleCov.start 'rails'
      require File.expand_path('../../config/environment', __FILE__)
      require 'rails/test_help'
      
      class ActiveSupport::TestCase
      
        fixtures :all
      
        protected
         def load_seeds
           load "#{Rails.root}/db/seeds.rb"
        end
      end
    2. El archivo test/application_system_test_case.rb:
    require "test_helper"
    require 'capybara/poltergeist'
       
    class NilLogger
        def puts * ; end
    end
       
    class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
       
      driven_by :poltergeist, screen_size: [1400, 1400], options: { 
        js_errors: true,
        logger: NilLogger.new#,
    #    phantomjs_logger: STDOUT,
    #    phantomjs_options: ['--debug=true'],
    #    debug: true 
      }
       
      def setup
    #    load "#{Rails.root}/db/seeds.rb"
      end
       
      def teardown
      end
       
    end
    1. En cada prueba del directorio test/system remplaza require "test_helper" por require 'application_system_test_case' y la clase en lugar de descender de ActionDispatch::IntegrationTest debe descender de ApplicationSystemTestCase. Si tienes, elimina include Capybara::DSL.
  • La gema chosen-rails no tiene actividad desde Ago.2018 y no soporta Rails 6 (ver https://github.com/varyonic/chosen-rails/commit/48c457fc9ef1c4c573b4dcdb9dc07034b46ed6b4) y podría tener otros problemas que no están siendo atendidos. Mientras la emplea con webpacker, provisionalmente usar:

    gem 'chosen-rails', git: 'https://github.com/vtamara/chosen-rails.git', branch: 'several-fixes'
    
  • En motores hemos notado que suelen producirse errores tan sólo ejecutando bin/rails si faltan algunas líneas en algunos archivos de configuración:

    • cannot load such file ..., requiere que test/dummy/config/boot.rb termine con:
      $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)   
      
      de hecho ese archivo completo debe ser:
      ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
      require 'bundler/setup' 
      require 'bootsnap/setup'
      $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)   
      
    • block in load_missing_constant': uninitialized constant .., requiere en test/dummy/config/application.rb:
      require 'sal7711_web'
      
Clone this wiki locally