Skip to content

Rails 8.1: NoMethodError when saving ActiveType::Object (NullPool#with_pool_transaction_isolation_level) #209

@cisolarix

Description

@cisolarix

ActiveType::Object raises NoMethodError (undefined method 'with_pool_transaction_isolation_level' for an instance of ActiveRecord::ConnectionAdapters::NullPool) on Rails 8.1

Summary

Forms inheriting from ActiveType::Object start failing on Rails 8.1.0/8.1.1 because the internal dummy connection returns an ActiveRecord::ConnectionAdapters::NullPool that does not implement with_pool_transaction_isolation_level. Calling save ends up invoking connection.with_pool_transaction_isolation_level and raises NoMethodError.

Environment

  • Ruby: 3.4.2
  • Rails: 8.1.1 (regression not present on 8.0.x)
  • ActiveType: 2.6.5
  • Database: MySQL

Steps to Reproduce

  1. Create a new Rails 8.1 project and add gem "active_type", "~> 2.6".

  2. Define a form object:

    class SignupForm < ActiveType::Object
      attribute :mobile_phone, :string
    end
  3. From a Rails console run:

    SignupForm.new(mobile_phone: '13800138000').save

Expected Behavior

save should execute without raising and return true (the same behavior observed on Rails 8.0.x).

Actual Behavior

A NoMethodError is raised:

NoMethodError (undefined method `with_pool_transaction_isolation_level' for ActiveRecord::ConnectionAdapters::NullPool:Class)

My guess

  • ActiveType::Object relies on a dummy connection (see ActiveType::NoTable::DummyConnection), which now inherits the new NullPool in Rails 8.1. The pool no longer implements with_pool_transaction_isolation_level, so any transaction-related call fails.

  • Rolling back to Rails 8.0.x restores the previous behavior.

  • Monkey patching the form base class with a no-op transaction method avoids the crash, but it only masks the regression:

    def transaction
      yield
    end

Suggested Fix

Consider updating the dummy connection/pool returned by ActiveType::Object so that it responds to with_pool_transaction_isolation_level (even as a no-op), or bypass transaction handling entirely for non-persistent objects.

Thanks for maintaining ActiveType!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions