This repository documents a breaking change with Rails 8, when running Postgresql databases.
Running
db:migrateon a fresh database now loads the schema before running migrations. Subsequent calls will run pending migrations. (If you need the previous behavior of running migrations from scratch instead of loading the schema file, this can be done by running db:migrate:reset which will drop and recreate the database before running migrations) -- Notable Changes (Ruby on Rails 8.0 Release Notes)
Changed in #52820.
In 7.2 ActiveRecord delegates Postgresql tooling (pg_dump) when the schema format is set to :sql
(docs).
This is still true in 8.0.
When multiple schema_search_paths are used across different environments (eg: develpment and
production) or across different installations (eg: SaaS and on-prem), ActiveRecord doesn't notice
the incompatibility and continues to attempt to load the incompatible db/structure.sql file. This
usually fails, but in the situation that customers are running an on-prem instance and it succeeds,
this behaviour can pollute schemas in use by other applications that are outside of the control
of the Rails application.
eg: in this repository, loading the production schema into development when running bash repro.sh.
Rails has previously run into issues with pg_dump and Postgres schemas: (#22345).
The issue being that using multiple schemas required filtering the pg_dump command to only export
schemas that are in use by the Rails application.
Unfortunately, from the pg_dump documentation, there's no mechanism to omit the schema names and create the export in a way that makes it schema agnostic.
Rails is already processing the output from pg_dump:
It should be possible for Rails to detect schema incompatibility, and not load db/structure.sql
when the schema(s) it was generated with do not match the schema(s) it would be loaded into.
To accomplish this, Rails could write a header to the file containing schema data, and then read it out before loading the file into Posgresql.