diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index a72b3c175e..1907215f70 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,11 @@ +* Dump the schema or structure of a database when calling db:migrate:name + + In previous versions of Rails, `rails db:migrate` would dump the schema of the database. In Rails 6, that holds true (`rails db:migrate` dumps all databases' schemas), but `rails db:migrate:name` does not share that behavior. + + Going forward, calls to `rails db:migrate:name` will dump the schema (or structure) of the database being migrated. + + *Kyle Thompson* + * Reset the `ActiveRecord::Base` connection after `rails db:migrate:name` When `rails db:migrate` has finished, it ensures the `ActiveRecord::Base` connection is reset to its original configuration. Going forward, `rails db:migrate:name` will have the same behavior. diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index 6d3c66138c..098ae4dbd8 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -106,6 +106,25 @@ db_namespace = namespace :db do db_namespace["_dump"].reenable end + namespace :_dump do + ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name| + # IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false + task name do + if ActiveRecord::Base.dump_schema_after_migration + case ActiveRecord::Base.schema_format + when :ruby then db_namespace["schema:dump:#{name}"].invoke + when :sql then db_namespace["structure:dump:#{name}"].invoke + else + raise "unknown schema format #{ActiveRecord::Base.schema_format}" + end + end + # Allow this task to be called as many times as required. An example is the + # migrate:redo task, which calls other two internally that depend on this one. + db_namespace["_dump:#{name}"].reenable + end + end + end + namespace :migrate do ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name| desc "Migrate #{name} database for current environment" @@ -114,6 +133,7 @@ db_namespace = namespace :db do db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name) ActiveRecord::Base.establish_connection(db_config) ActiveRecord::Tasks::DatabaseTasks.migrate + db_namespace["_dump:#{name}"].invoke ensure ActiveRecord::Base.establish_connection(original_db_config) end diff --git a/railties/test/application/rake/multi_dbs_test.rb b/railties/test/application/rake/multi_dbs_test.rb index 591f427131..26a031e44c 100644 --- a/railties/test/application/rake/multi_dbs_test.rb +++ b/railties/test/application/rake/multi_dbs_test.rb @@ -154,6 +154,44 @@ module ApplicationTests end end + def db_migrate_name_dumps_the_schema(name, schema_format) + add_to_config "config.active_record.schema_format = :#{schema_format}" + require "#{app_path}/config/environment" + + Dir.chdir(app_path) do + generate_models_for_animals + + assert_not(File.exist?("db/schema.rb")) + assert_not(File.exist?("db/animals_schema.rb")) + assert_not(File.exist?("db/structure.sql")) + assert_not(File.exist?("db/animals_structure.sql")) + + rails("db:migrate:#{name}") + + if schema_format == "ruby" + if name == "primary" + schema_dump = File.read("db/schema.rb") + assert_not(File.exist?("db/animals_schema.rb")) + assert_match(/create_table \"books\"/, schema_dump) + else + assert_not(File.exist?("db/schema.rb")) + schema_dump_animals = File.read("db/animals_schema.rb") + assert_match(/create_table \"dogs\"/, schema_dump_animals) + end + else + if name == "primary" + schema_dump = File.read("db/structure.sql") + assert_not(File.exist?("db/animals_structure.sql")) + assert_match(/CREATE TABLE (?:IF NOT EXISTS )?\"books\"/, schema_dump) + else + assert_not(File.exist?("db/structure.sql")) + schema_dump_animals = File.read("db/animals_structure.sql") + assert_match(/CREATE TABLE (?:IF NOT EXISTS )?\"dogs\"/, schema_dump_animals) + end + end + end + end + def db_test_prepare_name(name, schema_format) add_to_config "config.active_record.schema_format = :#{schema_format}" require "#{app_path}/config/environment" @@ -354,6 +392,23 @@ module ApplicationTests db_migrate_and_schema_dump_and_load "structure" end + + test "db:migrate:name dumps the schema for the primary database" do + db_migrate_name_dumps_the_schema("primary", "ruby") + end + + test "db:migrate:name dumps the schema for the animals database" do + db_migrate_name_dumps_the_schema("animals", "ruby") + end + + test "db:migrate:name dumps the structure for the primary database" do + db_migrate_name_dumps_the_schema("primary", "sql") + end + + test "db:migrate:name dumps the structure for the animals database" do + db_migrate_name_dumps_the_schema("animals", "sql") + end + test "db:migrate:name and db:schema:dump:name and db:schema:load:name works for the primary database" do require "#{app_path}/config/environment" db_migrate_and_schema_dump_and_load_one_database("schema", "primary")