Skip to content

Commit 1daec9b

Browse files
committed
Fix migration ordering for bin/rails db:prepare across databases
1 parent cacb847 commit 1daec9b

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

activerecord/lib/active_record/tasks/database_tasks.rb

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,17 @@ def prepare_all
192192

193193
seed = true
194194
end
195+
end
196+
end
195197

196-
migrate
197-
dump_schema(db_config) if ActiveRecord.dump_schema_after_migration
198+
each_current_environment(env) do |environment|
199+
db_configs_with_versions(environment).sort.each do |version, db_configs|
200+
db_configs.each do |db_config|
201+
with_temporary_pool(db_config) do
202+
migrate(version)
203+
dump_schema(db_config) if ActiveRecord.dump_schema_after_migration
204+
end
205+
end
198206
end
199207
end
200208

@@ -255,10 +263,10 @@ def migrate(version = nil)
255263
Migration.verbose = verbose_was
256264
end
257265

258-
def db_configs_with_versions # :nodoc:
266+
def db_configs_with_versions(environment = env) # :nodoc:
259267
db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
260268

261-
with_temporary_pool_for_each do |pool|
269+
with_temporary_pool_for_each(env: environment) do |pool|
262270
db_config = pool.db_config
263271
versions_to_run = pool.migration_context.pending_migration_versions
264272
target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
@@ -580,10 +588,7 @@ def class_for_adapter(adapter)
580588
end
581589

582590
def each_current_configuration(environment, name = nil)
583-
environments = [environment]
584-
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
585-
586-
environments.each do |env|
591+
each_current_environment(environment) do |env|
587592
configs_for(env_name: env).each do |db_config|
588593
next if name && name != db_config.name
589594

@@ -592,6 +597,12 @@ def each_current_configuration(environment, name = nil)
592597
end
593598
end
594599

600+
def each_current_environment(environment, &block)
601+
environments = [environment]
602+
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
603+
environments.each(&block)
604+
end
605+
595606
def each_local_configuration
596607
configs_for.each do |db_config|
597608
next unless db_config.database

railties/test/application/rake/multi_dbs_test.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,35 @@ class ThreeMigration < ActiveRecord::Migration::Current
566566
end
567567
end
568568

569+
test "db:prepare respects timestamp ordering across databases" do
570+
require "#{app_path}/config/environment"
571+
app_file "db/migrate/01_one_migration.rb", <<-MIGRATION
572+
class OneMigration < ActiveRecord::Migration::Current
573+
end
574+
MIGRATION
575+
576+
app_file "db/animals_migrate/02_two_migration.rb", <<-MIGRATION
577+
class TwoMigration < ActiveRecord::Migration::Current
578+
end
579+
MIGRATION
580+
581+
app_file "db/animals_migrate/04_four_migration.rb", <<-MIGRATION
582+
class FourMigration < ActiveRecord::Migration::Current
583+
end
584+
MIGRATION
585+
586+
app_file "db/migrate/03_three_migration.rb", <<-MIGRATION
587+
class ThreeMigration < ActiveRecord::Migration::Current
588+
end
589+
MIGRATION
590+
591+
Dir.chdir(app_path) do
592+
output = rails "db:prepare"
593+
entries = output.scan(/^== (\d+).+migrated/).map(&:first).map(&:to_i)
594+
assert_equal [1, 2, 3, 4] * 2, entries # twice because for test env too
595+
end
596+
end
597+
569598
test "migrations in different directories can have the same timestamp" do
570599
require "#{app_path}/config/environment"
571600
app_file "db/migrate/01_one_migration.rb", <<-MIGRATION

0 commit comments

Comments
 (0)