Skip to content

Support Rails 7.1 and 7.2 - #45

Merged
cardmagic merged 1 commit into
mainfrom
feat/support-rails-7-1
Aug 18, 2026
Merged

Support Rails 7.1 and 7.2#45
cardmagic merged 1 commit into
mainfrom
feat/support-rails-7-1

Conversation

@cardmagic

Copy link
Copy Markdown
Owner

Adds to the untagged 0.13.3 release.

The gemspec required Rails 8.0 from the first release commit, so applications on
the two prior Rails lines could not add the gem. Measuring the suite against
those lines shows the floor was higher than the code needs.

What the measurement showed

Full suite, SQLite, with the gemspec floor relaxed and no other change:

Rails Ruby Result
7.2.3 3.3.9 532 runs, 1 failure, 15 skips
7.1.6 3.3.9 532 runs, 1 failure, 15 skips
7.1.6 4.0.5 532 runs, 1 failure, 15 skips
7.0.10 3.3.9 cannot load: sqlite3 ~> 1.4 conflict

The single failure was the same one in all three passing runs, and it asserts a
Rails 8 error class rather than a behaviour:

EnqueueLockRetryTest#test_a_permanently_locked_database_still_raises_rather_than_hanging
[ActiveRecord::StatementTimeout] exception expected, not
Class: <ActiveRecord::StatementInvalid>
Message: <"SQLite3::BusyException: database is locked">

Rails 8 maps an exhausted SQLite busy handler to StatementTimeout. Rails 7.1
and 7.2 leave it as the StatementInvalid that StatementTimeout subclasses.
The library's own retry predicate walks the cause chain for
BusyException|BusyError, so it never depended on the Rails 8 class. The
assertion moves to the parent class and keeps the /database is locked/ match,
which is what the caller actually relies on.

Rails 7.0 is out of range

Its SQLite adapter requires sqlite3 ~> 1.4:

Error loading the 'sqlite3' Active Record adapter. Missing a gem it depends on?
can't activate sqlite3 (~> 1.4), already activated sqlite3-2.9.6

The busy-handler control this gem depends on (busy_handler_timeout=) arrived
in sqlite3 2.x, so the two cannot be loaded together. Supporting 7.0 would
mean giving up SQLite, which the gem advertises.

Change

  • Gem dependencies drop from >= 8.0 to >= 7.1 for actioncable,
    actionpack, actionview, activerecord, activesupport, and railties.
    rack >= 3.1 is unchanged and still resolves on 7.1.
  • The bundled migrations declare ActiveRecord::Migration[7.1]. [8.0] raises
    Unknown migration version on 7.x. Under Rails 8 the compatibility layer
    between [7.1] and [8.0] only changes remove_foreign_key, and no Solid
    Objects migration calls it, so an install built at [7.1] gets the same
    schema as one built at [8.0].
  • The compatibility CI matrix runs Ruby 3.3, 3.4, and 4.0 against Rails 7.1,
    7.2, 8.0, and 8.1.
  • README, docs/development.md, AGENTS.md, docs/roadmap.md, and
    CHANGELOG.md record the new floor.

Limitation recorded

The compatibility job runs SQLite only. The PostgreSQL and MySQL jobs run on the
newest Rails, so adapter behaviour on Rails 7.1 and 7.2 is unmeasured against
those servers. docs/roadmap.md states this rather than implying full coverage.

Validation

bundle exec rake on Rails 8.1.3.1 / Ruby 4.0.5: 535 runs, 1768 assertions,
0 failures, 0 errors, 15 skips. Standard Ruby, RuboCop, RBS, Steep, and Brakeman
all clean. The skip count matches main.

The gemspec required Rails 8.0 from the first release, so applications on
the two prior Rails lines could not add the gem at all. Measuring the
suite against those lines shows the floor was higher than the code needs.

On Rails 7.1 and 7.2 the suite fails one test, and that test asserts a
Rails 8 error class rather than a behaviour: Rails 8 maps an exhausted
SQLite busy handler to StatementTimeout, and 7.1 and 7.2 leave it as the
StatementInvalid that timeout subclasses. The message the caller relies
on is identical, so the assertion moves to the parent class and keeps the
message match.

The bundled migrations declared ActiveRecord::Migration[8.0], which
raises Unknown migration version on 7.x. They now declare [7.1]. Under
Rails 8 the compatibility layer between the two only changes
remove_foreign_key, and no Solid Objects migration calls it, so an
install built at [7.1] gets the same schema as one built at [8.0].

Rails 7.0 stays out of range. Its SQLite adapter requires sqlite3 ~> 1.4,
and the busy-handler control this gem depends on arrived in sqlite3 2.x,
so the two cannot be loaded together.

The compatibility matrix now runs Ruby 3.3, 3.4, and 4.0 against Rails
7.1, 7.2, 8.0, and 8.1. That job runs SQLite only, so adapter behaviour
on the older lines is unmeasured against PostgreSQL and MySQL, and the
roadmap says so.
@greptile-apps

greptile-apps Bot commented Aug 18, 2026

Copy link
Copy Markdown

Greptile Summary

The PR lowers the supported Rails floor from 8.0 to 7.1 and extends compatibility coverage accordingly.

  • Relaxes Rails component dependencies and changes bundled migrations to the Rails 7.1 compatibility version.
  • Adds Rails 7.1 and 7.2 to the Ruby compatibility CI matrix.
  • Makes the SQLite lock-exhaustion assertion portable across Rails exception mappings.
  • Updates installation, development, roadmap, agent, and release documentation.

Confidence Score: 5/5

The PR appears safe to merge, with the dependency, migration, CI, test, and documentation changes consistently reflecting the Rails 7.1 floor.

The requested Rails line is pinned consistently in compatibility jobs, the migration operations remain unchanged, and the broadened lock assertion preserves the observable exhausted-lock contract across supported Rails versions.

Important Files Changed

Filename Overview
solid_objects.gemspec Lowers the six Rails framework dependency floors consistently from 8.0 to 7.1 while retaining existing Rack and Thor constraints.
.github/workflows/ci.yml Expands the existing compatibility matrix to exercise Rails 7.1 and 7.2 across the supported Ruby versions.
db/migrate/20260805000000_create_solid_objects_tables.rb Changes the migration compatibility superclass to 7.1 without altering schema operations.
db/migrate/20260806000000_add_state_revision_to_solid_objects_instances.rb Changes the additive migration compatibility superclass to 7.1 without altering its column definition.
db/migrate/20260813000000_rename_message_dispatch_columns.rb Changes the reversible rename migration compatibility superclass to 7.1 without altering its constraints or rename sequence.
test/integration/enqueue_lock_retry_test.rb Broadens the expected exception to the cross-version parent class while retaining the database-lock message assertion and documenting the reason.

Reviews (1): Last reviewed commit: "Support Rails 7.1 and 7.2" | Re-trigger Greptile

@cardmagic
cardmagic merged commit 510f592 into main Aug 18, 2026
60 of 61 checks passed
@cardmagic
cardmagic deleted the feat/support-rails-7-1 branch August 18, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant