aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2019-07-30 16:56:32 -0400
committereileencodes <eileencodes@gmail.com>2019-08-02 15:22:11 -0400
commitbfec23aecb71b351b84e4c4592494f68f4d47be2 (patch)
tree5708bc4bd286582c4597aa1db745fba7690acd50
parent1c7207a22faca3f07ee9aee1dc00a5b01286de2f (diff)
downloadrails-bfec23aecb71b351b84e4c4592494f68f4d47be2.tar.gz
rails-bfec23aecb71b351b84e4c4592494f68f4d47be2.tar.bz2
rails-bfec23aecb71b351b84e4c4592494f68f4d47be2.zip
Fix `PG::ConnectionBad` error when running fixtures
At first this appeared to be a multi-db bug but after some invesitgation it was clear that this can occur just by calling `establish_connection` from ApplicationRecord. After some investigation we found that this only occurred when using fixtures. The console boots fine, the server runs fine, and the tests even run fine if we used paralellization or eager loading in the tests. I tracked the issue down to the line that calls `self.connection_specification_name = name` in the SchemaMigration changes for Rails 6.0. But how can this be? That is not that major of a change? How could `connection_specification_name` be a problem? First `connection_specification_name` caches the name of the connection specificatio. Second, fixtures were incorrectly holding onto a reference to that connection. So when you went to run the tests the models wouldn't be connected and when the fixtures tried to load the data it would choke on that unconnected database. The changes here move the connection into a lambda so we can call it when we need it rather than blowing up before the model is connected. Fixes #36743 Co-authored-by: Aaron Patterson <aaron.patterson@gmail.com>
-rw-r--r--activerecord/lib/active_record/fixtures.rb17
1 files changed, 11 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 3df4b3c87f..e4b958f1b9 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -553,15 +553,15 @@ module ActiveRecord
end
end
- def create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base)
+ def create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base, &block)
fixture_set_names = Array(fixture_set_names).map(&:to_s)
class_names = ClassCache.new class_names, config
# FIXME: Apparently JK uses this.
- connection = block_given? ? yield : ActiveRecord::Base.connection
+ connection = block_given? ? block : lambda { ActiveRecord::Base.connection }
fixture_files_to_read = fixture_set_names.reject do |fs_name|
- fixture_is_cached?(connection, fs_name)
+ fixture_is_cached?(connection.call, fs_name)
end
if fixture_files_to_read.any?
@@ -571,9 +571,9 @@ module ActiveRecord
class_names,
connection,
)
- cache_fixtures(connection, fixtures_map)
+ cache_fixtures(connection.call, fixtures_map)
end
- cached_fixtures(connection, fixture_set_names)
+ cached_fixtures(connection.call, fixture_set_names)
end
# Returns a consistent, platform-independent identifier for +label+.
@@ -612,7 +612,11 @@ module ActiveRecord
def insert(fixture_sets, connection) # :nodoc:
fixture_sets_by_connection = fixture_sets.group_by do |fixture_set|
- fixture_set.model_class&.connection || connection
+ if fixture_set.model_class
+ fixture_set.model_class.connection
+ else
+ connection.call
+ end
end
fixture_sets_by_connection.each do |conn, set|
@@ -623,6 +627,7 @@ module ActiveRecord
table_rows_for_connection[table].unshift(*rows)
end
end
+
conn.insert_fixtures_set(table_rows_for_connection, table_rows_for_connection.keys)
# Cap primary key sequences to max(pk).