Ruby on Rails 8: Novità e Guida Completa alla Migrazione 2026

Rails 8 introduce la Solid Trifecta, l'autenticazione nativa, Kamal 2 e Propshaft. Guida completa con esempi di codice e passaggi per la migrazione da Rails 7.

Ruby on Rails 8 novità e guida alla migrazione illustrazione

Ruby on Rails 8 segna il rilascio più importante del framework dalla versione 7, introducendo alternative native a Redis basate su database, autenticazione integrata e uno stack di deploy completamente riprogettato. Pubblicato a novembre 2024 e consolidato con Rails 8.1 a ottobre 2025, questo ciclo di versioni elimina dipendenze esterne che per anni hanno richiesto infrastruttura dedicata. Redis, Sprockets, Capistrano: componenti che Rails 8 rende opzionali grazie ad alternative integrate, gestite direttamente dal database relazionale. Per i team di sviluppo italiani, questa versione semplifica in modo significativo l'architettura di produzione e riduce sensibilmente i costi operativi.

Rails 8 in sintesi

Rails 8 sostituisce Redis con la Solid Trifecta (Solid Queue, Solid Cache, Solid Cable), include un generatore di autenticazione nativo, adotta Propshaft come pipeline di asset predefinito e integra Kamal 2 per i deploy senza interruzioni di servizio. Ruby 3.2 o superiore è obbligatorio.

La Solid Trifecta: infrastruttura basata su database

Prima di Rails 8, qualsiasi applicazione in produzione seria dipendeva da Redis per tre funzioni critiche: i job in background, la cache e il pub/sub WebSocket. La Solid Trifecta sostituisce questi tre componenti con adattatori compatibili con PostgreSQL, MySQL e SQLite, gestiti direttamente dal database relazionale esistente.

Il vantaggio operativo è immediato: non è più necessario configurare, monitorare e mantenere un'istanza Redis separata. Il compromesso riguarda le prestazioni grezze. Redis rimane più veloce negli scenari ad altissimo throughput, ma per la stragrande maggioranza delle applicazioni, gli adattatori basati su database offrono prestazioni più che sufficienti. Basecamp, l'applicazione di punta di 37signals, gestisce un Solid Cache da 10 TB in produzione con una retention di 60 giorni.

Solid Queue: i job in background senza Redis

Solid Queue sostituisce Sidekiq, Resque o Delayed Job come backend Active Job basato su database. Sfrutta FOR UPDATE SKIP LOCKED su PostgreSQL 9.5+ e MySQL 8.0+, con un meccanismo di fallback per SQLite.

ruby
# config/environments/production.rb
config.active_job.queue_adapter = :solid_queue

# config/solid_queue.yml
production:
  dispatchers:
    - polling_interval: 1
      batch_size: 500
  workers:
    - queues: "*"
      threads: 5
      processes: 2
      polling_interval: 0.1

Il plugin Puma avvia Solid Queue insieme al server web in ambiente di sviluppo, evitando la necessità di lanciare un processo separato:

ruby
# config/puma.rb
plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"] || Rails.env.development?

Solid Queue supporta job ricorrenti, controlli di concorrenza e funzionalità avanzate come la pausa e la ripresa per coda. Per le applicazioni che elaborano meno di 10.000 job al minuto, gestisce il carico senza difficoltà.

Solid Cache e Solid Cable

Solid Cache archivia i frammenti HTML nella cache del database invece che in Memcached o Redis. Lo storage su disco (SSD/NVMe) costa una frazione del prezzo della RAM, consentendo pool di cache molto più ampi con tempi di retention superiori.

ruby
# config/environments/production.rb
config.cache_store = :solid_cache_store

Solid Cable sostituisce l'adattatore pub/sub Redis di Action Cable. I messaggi WebSocket vengono scritti in una tabella e interrogati ogni 100 ms per impostazione predefinita. Il risultato è una comunicazione quasi in tempo reale per la maggior parte dei casi d'uso, con una pulizia automatica dei messaggi dopo 24 ore.

yaml
# config/cable.yml
production:
  adapter: solid_cable
  polling_interval: 0.1
  keep_messages_around_for: 1.day

Il generatore di autenticazione nativo

Rails 8 integra un generatore di autenticazione che produce lo scaffolding necessario per il login, il logout e il reset della password. Non è richiesta alcuna gem esterna per l'autenticazione di base.

bash
# Generate the authentication scaffolding
bin/rails generate authentication

Questo comando crea il modello User, il modello Session, il SessionsController, il PasswordsController e un concern Authentication. Il codice generato utilizza has_secure_password con bcrypt e include il rate limiting (10 tentativi di login ogni 3 minuti per IP).

ruby
# app/controllers/concerns/authentication.rb
module Authentication
  extend ActiveSupport::Concern

  included do
    before_action :require_authentication
    helper_method :authenticated?
  end

  private

  def require_authentication
    resume_session || request_authentication
  end

  def resume_session
    Current.session = find_session_by_cookie
  end

  def find_session_by_cookie
    Session.find_by(id: cookies.signed[:session_id]) if cookies.signed[:session_id]
  end

  def request_authentication
    session[:return_to_after_authenticating] = request.url
    redirect_to new_session_path
  end

  def authenticated?
    Current.session.present?
  end
end

Il reset della password si basa su token firmati con scadenza temporale, generati da has_secure_password, e non su token memorizzati nel database. Il generatore non include volutamente la registrazione utente, la verifica dell'indirizzo email né il login social. Il codice generato rappresenta una base solida da estendere, non un sostituto completo di Devise.

Ambito del generatore

Il generatore nativo copre login, logout e reset della password. La registrazione utente, la verifica email, OAuth e l'autenticazione multifattore devono essere aggiunti manualmente o tramite gem come Authentication Zero.

Gestione sicura dei parametri con params.expect

Rails 8 introduce params.expect, un'alternativa più rigorosa al tradizionale params.require.permit. Il nuovo metodo solleva un'eccezione quando le chiavi sono assenti, invece di restituire nil silenziosamente.

ruby
# Before (Rails 7)
def user_params
  params.require(:user).permit(:name, :email, :role)
end

# After (Rails 8)
def user_params
  params.expect(user: [:name, :email, :role])
end

Il metodo expect garantisce che la chiave :user esista e contenga solo gli attributi autorizzati. In caso di assenza, solleva immediatamente ActionController::ParameterMissing, prevenendo errori silenziosi nelle fasi successive del flusso di esecuzione.

Propshaft: il nuovo pipeline di asset predefinito

Propshaft sostituisce Sprockets come pipeline di asset predefinito. Mentre Sprockets gestiva compilazione, minificazione e fingerprinting in un sistema monolitico, Propshaft si concentra esclusivamente sul servizio e sul fingerprinting dei file statici.

Per il bundling JavaScript, Propshaft delega agli strumenti moderni: esbuild, Vite o Bun. L'elaborazione CSS passa attraverso Tailwind CLI o dart-sass. Il risultato è un pipeline di asset più veloce, più prevedibile e allineato con l'ecosistema frontend attuale.

ruby
# Gemfile (Rails 8 default)
gem "propshaft"

Le applicazioni esistenti che utilizzano Sprockets possono continuare a farlo senza alcun vincolo. Il percorso di migrazione consiste nel rimuovere le direttive specifiche di Sprockets (//= require) e adottare le import map o un bundler JavaScript.

Pronto a superare i tuoi colloqui su Ruby on Rails?

Pratica con i nostri simulatori interattivi, flashcards e test tecnici.

Kamal 2 e Thruster: deploy senza interruzioni

Rails 8 è preconfigurato con Kamal 2, uno strumento di deploy capace di trasformare un server Linux vergine in un server di produzione con un unico comando. Kamal 2 sostituisce Traefik con Kamal Proxy, un reverse proxy progettato appositamente per questo scopo.

bash
# Deploy to a fresh server
kamal setup

# Subsequent deployments
kamal deploy

Thruster si inserisce tra Kamal Proxy e Puma. Fornisce accelerazione X-Sendfile per il download dei file, compressione automatica degli asset (gzip/brotli) e supporto HTTP/2. Il Dockerfile generato da Rails 8 include Thruster per impostazione predefinita.

dockerfile
# Excerpt from Rails 8 generated Dockerfile
RUN gem install thruster
CMD ["thrust", "./bin/rails", "server"]

Questo stack tecnico (Kamal 2 + Kamal Proxy + Thruster + Puma) gestisce la terminazione SSL, i deploy senza downtime e i riavvii progressivi senza ricorrere a servizi esterni come Nginx o HAProxy.

SQLite potenziato per la produzione

Rails 8 migliora in modo significativo il supporto di SQLite in produzione. Il connection pooling, la modalità WAL e la concorrenza migliorata rendono SQLite utilizzabile per le applicazioni di piccole e medie dimensioni. Combinato con la Solid Trifecta, un singolo server può far funzionare un'applicazione Rails 8 interamente su SQLite, senza alcun server di database esterno.

yaml
# config/database.yml (SQLite production setup)
production:
  primary:
    adapter: sqlite3
    database: storage/production.sqlite3
    pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  cache:
    adapter: sqlite3
    database: storage/production_cache.sqlite3
  queue:
    adapter: sqlite3
    database: storage/production_queue.sqlite3
  cable:
    adapter: sqlite3
    database: storage/production_cable.sqlite3

Questa configurazione fa funzionare l'intero stack applicativo a partire da quattro file SQLite. Kamal monta la directory di storage come volume persistente, garantendo che i dati sopravvivano ai riavvii dei container.

Migrazione da Rails 7 a Rails 8

Il percorso di migrazione da Rails 7.2 a Rails 8.0 è lineare, a condizione che l'applicazione abbia previamente risolto gli avvisi di deprecazione. Le applicazioni su Rails 7.0 o 7.1 devono procedere per tappe: da 7.0 a 7.1, poi da 7.1 a 7.2, e infine da 7.2 a 8.0.

Prerequisiti da verificare

Rails 8 richiede Ruby 3.2 o superiore. Occorre verificare la versione di Ruby installata, assicurarsi che la suite di test passi con Rails 7.2 e controllare la compatibilità delle gem tramite RailsBump prima di avviare l'aggiornamento.

Passaggio 1: aggiornare le dipendenze

ruby
# Gemfile
gem "rails", "~> 8.0"
bash
bundle update rails

Passaggio 2: eseguire il task di aggiornamento

bash
bin/rails app:update

Questo comando aggiorna i file di configurazione ai valori predefiniti di Rails 8. È fondamentale esaminare ogni modifica con git diff. Le modifiche principali includono il nuovo valore predefinito di Regexp.timeout (1 secondo), il comportamento aggiornato di db:migrate (caricamento dello schema sui database vuoti) e la configurazione di Propshaft.

Passaggio 3: gestire il riordinamento dello schema

Rails 8 riordina le colonne di schema.rb per rispecchiare l'ordine reale delle colonne nel database. Si consiglia di eseguire il dump dello schema immediatamente per isolare questa modifica cosmetica dalle vere modifiche di migrazione:

bash
bin/rails db:schema:dump
git add db/schema.rb
git commit -m "Reorder schema columns for Rails 8"

Passaggio 4: adottare le nuove funzionalità in modo graduale

La Solid Trifecta, Propshaft e il generatore di autenticazione restano opzionali per le applicazioni esistenti. È preferibile adottarli singolarmente una volta che l'aggiornamento principale è stabilizzato:

  1. Sostituire l'adattatore dei job con Solid Queue
  2. Passare lo store della cache a Solid Cache
  3. Migrare Action Cable a Solid Cable (se applicabile)
  4. Valutare la migrazione del pipeline di asset a Propshaft

Passaggio 5: modernizzare la gestione dei parametri

Sostituire le chiamate params.require.permit con params.expect in tutti i controller. Questa modifica è opzionale ma fortemente raccomandata per ottenere una validazione dei parametri più robusta.

Rails 8.1: i Continuable Job e il CI integrato

Rails 8.1, pubblicato a ottobre 2025, amplia le fondamenta poste da Rails 8 con due funzionalità di rilievo. I Continuable Job (ActiveJob::Continuable) suddividono i job di lunga durata in fasi ripristinabili. Se un server si riavvia durante un'importazione, il job riprende esattamente dal punto in cui si era interrotto, invece di ripartire da zero.

ruby
# app/jobs/import_records_job.rb
class ImportRecordsJob < ApplicationJob
  include ActiveJob::Continuable

  def perform(cursor:)
    records = Record.where("id > ?", cursor.value || 0).limit(1000)

    records.each do |record|
      process(record)
      cursor.advance(record.id)
    end
  end
end

Rails 8.1 introduce inoltre una configurazione CI integrata e il rendering nativo di Markdown, riducendo ulteriormente le dipendenze esterne.

Conclusione

Rails 8 rappresenta un punto di svolta nella filosofia del framework, privilegiando la semplicità operativa senza compromettere le funzionalità. I punti essenziali da ricordare:

  • La Solid Trifecta (Queue, Cache, Cable) elimina Redis come dipendenza obbligatoria per job, cache e WebSocket
  • Il generatore di autenticazione nativo fornisce una base per l'autenticazione basata su sessioni senza gem di terze parti
  • params.expect sostituisce params.require.permit con una gestione dei parametri più rigorosa e sicura
  • Propshaft sostituisce Sprockets come pipeline di asset predefinito, delegando il bundling agli strumenti moderni
  • Kamal 2 e Thruster consentono deploy senza interruzioni senza ricorrere a Nginx o Capistrano
  • La migrazione da Rails 7.2 è incrementale: aggiornamento delle dipendenze, esecuzione di app:update e adozione graduale delle nuove funzionalità
  • Rails 8.1 aggiunge i Continuable Job e il CI integrato per i team che desiderano ridurre gli strumenti esterni

Inizia a praticare!

Metti alla prova le tue conoscenze con i nostri simulatori di colloquio e test tecnici.

Tag

#ruby-on-rails
#rails-8
#tutorial
#migration
#solid-queue
#solid-cache
#authentication

Condividi

Articoli correlati