Skip to content

Fix: delegate structure_dump_flags and structure_load_flags to ActiveRecord - #371

Open
granti wants to merge 3 commits into
ilyakatz:mainfrom
granti:fix/rails-72-structure-dump-flags-error
Open

granti wants to merge 3 commits into
ilyakatz:mainfrom
granti:fix/rails-72-structure-dump-flags-error

Conversation

@granti

@granti granti commented Apr 16, 2026

Copy link
Copy Markdown

Fix: delegate structure_dump_flags and structure_load_flags to ActiveRecord

Problem

When running rails db:prepare:with_data with structure.sql format on Rails 7.2+, the following error occurs:

NameError: undefined local variable or method 'structure_dump_flags' for module primary

          if structure_dump_flags.is_a?(Hash)
             ^^^^^^^^^^^^^^^^^^^^
Did you mean?  structure_dump_flags_for

Root Cause

DataMigrate::DatabaseTasks uses extend ActiveRecord::Tasks::DatabaseTasks to copy methods from ActiveRecord. However, structure_dump_flags and structure_load_flags are defined as mattr_accessor on the original module, which stores values on ActiveRecord::Tasks::DatabaseTasks itself.

When dump_schema is called from DataMigrate::DatabaseTasks, it internally calls structure_dump_flags_for, which tries to access structure_dump_flags - but that accessor doesn't exist on DataMigrate::DatabaseTasks.

Solution

Add delegation methods that forward calls to the original ActiveRecord::Tasks::DatabaseTasks module:

def self.structure_dump_flags
  ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags
end

def self.structure_load_flags
  ActiveRecord::Tasks::DatabaseTasks.structure_load_flags
end

Testing

  • Added 5 new tests for the delegation methods
  • Verified all 75 tests pass on Rails 7.2, 8.0, and 8.1
  • Tests cover:
    • Proper delegation to ActiveRecord::Tasks::DatabaseTasks
    • Handling nil values
    • No NameError when accessing the flags

Reproduction Steps

  1. Create a Rails 7.2+ app with config.active_record.schema_format = :sql
  2. Add data_migrate gem
  3. Run rails db:prepare:with_data
  4. Observe NameError

After this fix, the command completes successfully.

…Record

When DataMigrate::DatabaseTasks extends ActiveRecord::Tasks::DatabaseTasks,
the mattr_accessor methods (structure_dump_flags and structure_load_flags)
are not properly inherited because they store values on the original module.

This causes a NameError when db:prepare:with_data calls dump_schema, which
internally calls structure_dump_flags_for that tries to access these accessors:

  NameError: undefined local variable or method 'structure_dump_flags' for module primary

This fix adds delegation methods that forward calls to the original
ActiveRecord::Tasks::DatabaseTasks module.

Fixes issue when using db:prepare:with_data with structure.sql format
in Rails 7.2+.
@vprigent

vprigent commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Hi Granti!

Thanks a lot for fixing this.
Upon testing, I switched a test app to your branch and ran
bundle exec rails db:migrate:with_data followed by
bundle exec rails db:drop db:prepare:with_data

it looks like when a data_schema.rb file is present, the current solution explodes?

Parse error near line 1: near "DataMigrate": syntax error
  DataMigrate::Data.define(version: 2025_10_27_185053)
  ^--- error here
bin/rails aborted!

Just wanted to report it, seems its limited to the codepath when using
config.active_record.schema_format = :sql

I'm pretty sure it would still be broken without your patch.

When schema_format is :sql, prepare was loading data_schema.rb through
structure_load. Delegate AR load/dump to ActiveRecord::Tasks::DatabaseTasks
and always load data_schema as ruby.

Co-authored-by: Cursor <cursoragent@cursor.com>

@houndci-bot houndci-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Some files could not be reviewed due to errors:

.rubocop.yml: Lint/BlockAlignment has the wrong namespace - should be Layout
.rubocop.yml: Lint/BlockAlignment has the wrong namespace - should be Layout
.rubocop.yml: Lint/ConditionPosition has the wrong namespace - should be Layout
Warning: unrecognized cop Lint/LiteralInCondition found in .rubocop.yml
Error: Unknown Ruby version 3.1 found in `TargetRubyVersion` parameter (in .rubocop.yml).
Supported versions: 2.1, 2.2, 2.3, 2.4, 2.5

@granti

granti commented Sep 13, 2026

Copy link
Copy Markdown
Author

Hi Vincent,

Thank you for testing this against your test bed, and for the clear repro. That was very helpful.

You were right: the parse error is a separate bug from the structure_dump_flags NameError. prepare_all_with_data was calling load_schema with ActiveRecord’s schema_format, but DataMigrate::DatabaseTasks#schema_dump_path always points at data_schema.rb. With config.active_record.schema_format = :sql, that meant Ruby was being passed to structure_load. The same mix-up also affected the dump path after migrate.

I have pushed a follow-up commit that keeps the two schemas separate, in line with db:structure:load:with_data / db:schema:load:with_data:

  • load/dump the ActiveRecord schema through ActiveRecord::Tasks::DatabaseTasks (so :sql uses structure.sql)
  • always load data_schema.rb as :ruby
  • keep the original structure_dump_flags / structure_load_flags delegation

If you have a moment to re-run db:migrate:with_data followed by db:drop db:prepare:with_data on your test bed, I would be grateful for a second look. Happy to adjust further if anything still looks off.

Thanks again,
Ian

Hound was failing because .hound.yml used the old ruby: key and default
RuboCop 0.54 cannot parse TargetRubyVersion 3.1 or the renamed cops in
.ruby-style.yml. Pin Hound to RuboCop 1.22.1, modernize the style file,
and extract prepare schema helpers so new code stays within Metrics limits.

Co-authored-by: Cursor <cursoragent@cursor.com>

@houndci-bot houndci-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Some files could not be reviewed due to errors:

Configuration file not found: .ruby-style.yml
Configuration file not found: .ruby-style.yml

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.

3 participants