spring
spring copied to clipboard
ActiveRecord::Base isn't necessarily the only class with a connection
Sometimes, different models need to connect to different databases or as different users.
In lib/spring/application.rb, we make the assumption that the only model that needs to connect to the database is ActiveRecord::Base.
This should be configurable, i.e.
Rails.application.config.established_connections = [ActiveRecord::Base, SomeModelWithItsOwnConnection]
# This could default to [ActiveRecord::Base] or to []
module Spring
class Application
def disconnect_database
Rails.application.config.established_connections.each do |model_class|
model_class.remove_connection if model_class.configurations.any?
end
end
def connect_database
Rails.application.config.established_connections.each do |model_class|
model_class.establish_connection if model_class.configurations.any?
end
end
def active_record_configured?
# This method is no longer necessary
end
end
end
This, of course, assumes that the way the user is overriding the connection is by defining configurations on SomeModelWithItsOwnConnection and then calling establish_connection, so without first checking that the Rails docs identify that as the recommended practice, I don't know if the above is the right approach.
Is not this already possible using the after_fork hook? https://github.com/rails/spring#running-code-after-forking
It looks like is possible that way--thanks for pointing me to the correct docs.
IMO, there is still a strong argument for making this more easily configurable. The code is already there--it's just that ActiveRecord::Base is hard-coded into it. Copying the logic into an after_fork would be duplicating code that doesn't need to be duplicated.
I know this is a bit of an old one but I also recently bumped into this issue which was causing some of my tests to randomly fail.
I'm not sure if it was possible at the time, but we should be able to extract the names of the existing database connections and then re-establish them quite reliably with something like this:
connection_names = ActiveRecord::Base.connection_handler.connection_pools.map(&:spec).map(&:name)
connection_names.each do |connection_name|
ActiveRecord::Base.connection_handler.establish_connection(connection_name)
end
I'd be happy to make a pull request for this to remove the need for the after_fork hook.