diff --git a/lib/data_migrate/database_tasks.rb b/lib/data_migrate/database_tasks.rb index 517d7dc..907a6d9 100644 --- a/lib/data_migrate/database_tasks.rb +++ b/lib/data_migrate/database_tasks.rb @@ -9,6 +9,17 @@ module DatabaseTasks extend ActiveRecord::Tasks::DatabaseTasks extend self + # Delegate structure_dump_flags and structure_load_flags to ActiveRecord::Tasks::DatabaseTasks. + # These are mattr_accessors on the original module that don't get properly extended, + # causing NameError when dump_schema calls structure_dump_flags_for in Rails 7.2+. + def self.structure_dump_flags + ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags + end + + def self.structure_load_flags + ActiveRecord::Tasks::DatabaseTasks.structure_load_flags + end + if respond_to?(:register_task) register_task(/mysql/, "ActiveRecord::Tasks::MySQLDatabaseTasks") register_task(/trilogy/, "ActiveRecord::Tasks::MySQLDatabaseTasks") diff --git a/spec/data_migrate/database_tasks_spec.rb b/spec/data_migrate/database_tasks_spec.rb index 4d3b585..ec1b1da 100644 --- a/spec/data_migrate/database_tasks_spec.rb +++ b/spec/data_migrate/database_tasks_spec.rb @@ -103,6 +103,71 @@ end end + describe "structure_dump_flags delegation" do + it "delegates structure_dump_flags to ActiveRecord::Tasks::DatabaseTasks" do + original_flags = ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags + begin + ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = { postgresql: "--no-comments" } + expect(subject.structure_dump_flags).to eq({ postgresql: "--no-comments" }) + ensure + ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = original_flags + end + end + + it "delegates structure_load_flags to ActiveRecord::Tasks::DatabaseTasks" do + original_flags = ActiveRecord::Tasks::DatabaseTasks.structure_load_flags + begin + ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = { postgresql: "--quiet" } + expect(subject.structure_load_flags).to eq({ postgresql: "--quiet" }) + ensure + ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = original_flags + end + end + + it "returns nil when structure_dump_flags is not set" do + original_flags = ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags + begin + ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = nil + expect(subject.structure_dump_flags).to be_nil + ensure + ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = original_flags + end + end + + it "returns nil when structure_load_flags is not set" do + original_flags = ActiveRecord::Tasks::DatabaseTasks.structure_load_flags + begin + ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = nil + expect(subject.structure_load_flags).to be_nil + ensure + ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = original_flags + end + end + + context "when dump_schema calls structure_dump_flags_for" do + # This test ensures that the structure_dump_flags delegation works correctly + # when dump_schema is called with :sql format, which uses structure_dump internally. + # Without the delegation, this raises: + # NameError: undefined local variable or method 'structure_dump_flags' for module primary + it "does not raise NameError when accessing structure_dump_flags" do + db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new( + 'test', + 'primary', + adapter: "sqlite3", + database: "spec/db/test.db" + ) + + # Verify the delegation methods are accessible and don't raise errors + expect { subject.structure_dump_flags }.not_to raise_error + expect { subject.structure_load_flags }.not_to raise_error + + # These methods should return the same values as ActiveRecord::Tasks::DatabaseTasks + expect(subject.structure_dump_flags).to eq(ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags) + expect(subject.structure_load_flags).to eq(ActiveRecord::Tasks::DatabaseTasks.structure_load_flags) + end + end + end + describe :prepare_all_with_data do let(:db_config) do ActiveRecord::DatabaseConfigurations::HashConfig.new(