Last active
July 15, 2020 18:53
-
-
Save wycleffsean/bcdc9fe9ed5ad707abffafdcd0d4d638 to your computer and use it in GitHub Desktop.
Defer class code until a db connection is established
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Enable class level code to lazily access database information. | |
# Often ActiveRecord class definitions will rely upon the table schema | |
# information. For example the following snippets would acquire a database | |
# connection: | |
# ignore_columns :foo | |
# # or | |
# attribute_names.each ... | |
# This results in rails accessing the database when booting, resulting in | |
# ridiculous behavior like this: | |
# bin/rake db:setup | |
# ActiveRecord::NoDatabaseError: Unknown database 'development' | |
# | |
# ...well yeah, duh. This module extends ActiveRecord to enable the lazy | |
# definition of class code - i.e. the code will execute the moment a | |
# connection is establish "naturally" rather than forcing one. e.g. | |
# once_connected { ignore_columns :foo } | |
module DeferredConnectionHandling | |
def self.extended(klass) | |
klass.class_eval do | |
@@database_has_connected = Concurrent::AtomicBoolean.new | |
end | |
end | |
def retrieve_connection | |
res = super | |
if @@database_has_connected.false? | |
@@database_has_connected.make_true | |
ActiveSupport.run_load_hooks(:database_connected) | |
end | |
res | |
end | |
def once_connected(&block) | |
ActiveSupport.on_load(:database_connected, self) do | |
class_eval(&block) | |
end | |
end | |
end | |
ActiveRecord::Base.extend(DeferredConnectionHandling) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment