Skip to content

Move migration compatibility behavior to per-adapter modules#57479

Open
yahonda wants to merge 1 commit into
rails:mainfrom
yahonda:per-adapter-migration-compatibility
Open

Move migration compatibility behavior to per-adapter modules#57479
yahonda wants to merge 1 commit into
rails:mainfrom
yahonda:per-adapter-migration-compatibility

Conversation

@yahonda

@yahonda yahonda commented May 27, 2026

Copy link
Copy Markdown
Member

Motivation / Background

Adapter-specific migration compatibility logic was scattered across a single monolithic Compatibility class with adapter_name string comparisons. This made it hard to maintain and impossible for third-party adapters to extend without monkey-patching (e.g. cockroachdb adapter, oracle-enhanced #2596, oracle-enhanced #2710).

Detail

Each built-in adapter now defines its own MigrationCompatibility module and returns it from the new migration_compatibility_module_for hook. Third-party adapters can override this hook to ship per-version legacy behavior without patching Rails internals.

The hook is registered on Mysql2Adapter and TrilogyAdapter (not AbstractMysqlAdapter) so third-party adapters subclassing the abstract class are not implicitly opted in.

Additional information

Verified that the CockroachDB adapter's monkey patch is no longer needed — migration_compatibility_module_for is inherited from PostgreSQLAdapter, and :datetime:timestamp conversion works correctly for Migration[6.1] on CockroachDB without any adapter-side patching.

Checklist

  • This Pull Request is related to one change. Unrelated changes should be opened in separate PRs.
  • Commit message has a detailed description of what changed and why.
  • Tests are added or updated if you fix a bug or add a feature.
  • CHANGELOG files are updated for the changed libraries if there is a behavior change or additional feature.

Adapter-specific migration compatibility logic was scattered across
a single monolithic Compatibility class with adapter_name string
comparisons. This made it hard to maintain and impossible for
third-party adapters to extend without monkey-patching.

Each built-in adapter now defines its own MigrationCompatibility
module and returns it from the new
`migration_compatibility_module_for` hook. Third-party adapters
(e.g. cockroachdb) can override this hook to ship per-version
legacy behavior without patching Rails internals.

The hook is registered on Mysql2Adapter and TrilogyAdapter (not
AbstractMysqlAdapter) so third-party adapters subclassing the
abstract class are not implicitly opted in.

The assembled module is included on the topmost user-defined class
in the migration ancestry, preserving the pre-refactor lookup order
where user overrides run ahead of adapter-specific code.
Migrator#apply_adapter_compatibility_module covers migrations that
override #migrate directly. Module caching uses
ObjectSpace::WeakMap to avoid leaking anonymous/reloaded classes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@yahonda yahonda force-pushed the per-adapter-migration-compatibility branch from 08a143f to 7d8af0f Compare May 27, 2026 10:39

@rafaelfranca rafaelfranca left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea but this removed all the simplicity of the superclass of the migration containing the version, now, if I get this correctly the code of that class changes the first time a migration is executed so it is hard to predict which behavior that class would have, it depends on modules included at runtime, that depends on which adapter is used. That is a lot of complexity to me.

A common design pattern to solve this problem is the strategy pattern, and we can avoid the inheritance complexity (module being included at runtime)

end

def migration_compatibility_module_for(migration_class)
nil

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove this

@yahonda

yahonda commented May 29, 2026

Copy link
Copy Markdown
Member Author

Agreed. I've started reworking it around the strategy pattern on a separate branch, and I'll open it as a separate pull request once it's ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants