diff --git a/lib/chrono_model.rb b/lib/chrono_model.rb index f90c232..2a2a583 100644 --- a/lib/chrono_model.rb +++ b/lib/chrono_model.rb @@ -2,6 +2,7 @@ require 'active_record' +require 'chrono_model/chrono' require 'chrono_model/conversions' require 'chrono_model/patches' require 'chrono_model/adapter' @@ -9,6 +10,9 @@ require 'chrono_model/time_gate' require 'chrono_model/version' +require 'chrono_model/railtie' if defined?(Rails::Railtie) +require 'chrono_model/db_console' if defined?(Rails::DBConsole) && Rails.version < '7.1' + module ChronoModel class Error < ActiveRecord::ActiveRecordError # :nodoc: end @@ -33,59 +37,30 @@ def self.history_models end end -if defined?(Rails::Railtie) - require 'chrono_model/railtie' -end +ActiveSupport.on_load :active_record do + extend ChronoModel::Chrono -ActiveRecord::Base.instance_eval do - # Checks whether this Active Recoed model is backed by a temporal table - # - def chrono? - return false unless connection.respond_to? :is_chrono? + # Hooks into Association#scope to pass the As-Of time automatically + # to methods that load associated ChronoModel records. + ActiveRecord::Associations::Association.prepend ChronoModel::Patches::Association - connection.is_chrono?(table_name) - end -end + # Hooks into Relation#build_arel to use `:joins` on your ChronoModels + # and join data from associated records As-Of time. + ActiveRecord::Relation.prepend ChronoModel::Patches::Relation -# Hooks into Association#scope to pass the As-Of time automatically -# to methods that load associated ChronoModel records. -# -ActiveRecord::Associations::Association.instance_eval do - prepend ChronoModel::Patches::Association -end + # Hooks in two points of the AR Preloader to preload As-Of time records of + # associated ChronoModels. is used by `.includes`, `.preload`, and `.eager_load`. + ActiveRecord::Associations::Preloader.prepend ChronoModel::Patches::Preloader -# Hooks into Relation#build_arel to use :joins on your ChronoModels -# and join data from associated records As-Of time. -# -ActiveRecord::Relation.instance_eval do - prepend ChronoModel::Patches::Relation -end + ActiveRecord::Associations::Preloader::Association.prepend ChronoModel::Patches::Preloader::Association -# Hooks in two points of the AR Preloader to preload As-Of time records of -# associated ChronoModels. is used by .includes, .preload and .eager_load. -# -ActiveRecord::Associations::Preloader.instance_eval do - prepend ChronoModel::Patches::Preloader -end - -ActiveRecord::Associations::Preloader::Association.instance_eval do - prepend ChronoModel::Patches::Preloader::Association -end + ActiveRecord::Associations::Preloader::ThroughAssociation.prepend ChronoModel::Patches::Preloader::ThroughAssociation -ActiveRecord::Associations::Preloader::ThroughAssociation.instance_eval do - prepend ChronoModel::Patches::Preloader::ThroughAssociation + ActiveRecord::Batches::BatchEnumerator.prepend ChronoModel::Patches::Batches::BatchEnumerator end -ActiveRecord::Batches::BatchEnumerator.instance_eval do - prepend ChronoModel::Patches::Batches::BatchEnumerator -end +ActiveSupport.on_load :after_initialize do + next if Rails.application.config.active_record.schema_format == :sql -if defined?(Rails::DBConsole) && Rails.version < '7.1' - Rails::DBConsole.instance_eval do - if Rails.version < '6.1' - prepend ChronoModel::Patches::DBConsole::Config - else - prepend ChronoModel::Patches::DBConsole::DbConfig - end - end + raise 'In order to use ChronoModel, set `config.active_record.schema_format` to `:sql`' end diff --git a/lib/chrono_model/chrono.rb b/lib/chrono_model/chrono.rb new file mode 100644 index 0000000..8385303 --- /dev/null +++ b/lib/chrono_model/chrono.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module ChronoModel + # A module to add to ActiveRecord::Base to check if they are backed by + # temporal tables. + module Chrono + # Checks whether this Active Record model is backed by a temporal table + # + # @return [Boolean] false if the connection does not respond to is_chrono? + # the result of connection.is_chrono?(table_name) otherwise + def chrono? + return false unless connection.respond_to? :is_chrono? + + connection.is_chrono?(table_name) + end + end +end diff --git a/lib/chrono_model/db_console.rb b/lib/chrono_model/db_console.rb new file mode 100644 index 0000000..e395f09 --- /dev/null +++ b/lib/chrono_model/db_console.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'chrono_model/patches/db_console' + +if Rails.version < '6.1' + Rails::DBConsole.prepend ChronoModel::Patches::DBConsole::Config +else + Rails::DBConsole.prepend ChronoModel::Patches::DBConsole::DbConfig +end diff --git a/lib/chrono_model/patches.rb b/lib/chrono_model/patches.rb index d4f2e1e..4130e9a 100644 --- a/lib/chrono_model/patches.rb +++ b/lib/chrono_model/patches.rb @@ -7,5 +7,4 @@ require 'chrono_model/patches/relation' require 'chrono_model/patches/preloader' require 'chrono_model/patches/association' -require 'chrono_model/patches/db_console' require 'chrono_model/patches/batches' diff --git a/lib/chrono_model/railtie.rb b/lib/chrono_model/railtie.rb index 951555b..7d4b650 100644 --- a/lib/chrono_model/railtie.rb +++ b/lib/chrono_model/railtie.rb @@ -6,14 +6,6 @@ module ChronoModel class Railtie < ::Rails::Railtie TASKS_CLASS = ActiveRecord::Tasks::ChronomodelDatabaseTasks - def task_config - if Rails.version < '6.1' - ActiveRecord::Tasks::DatabaseTasks.current_config.with_indifferent_access - else - ActiveRecord::Base.connection_db_config - end - end - # Register our database tasks under our adapter name if Rails.version < '5.2' ActiveRecord::Tasks::DatabaseTasks.register_task(/chronomodel/, TASKS_CLASS) @@ -22,8 +14,12 @@ def task_config end rake_tasks do - if Rails.application.config.active_record.schema_format != :sql - raise 'In order to use ChronoModel, config.active_record.schema_format must be :sql!' + def task_config + if Rails.version < '6.1' + ActiveRecord::Tasks::DatabaseTasks.current_config.with_indifferent_access + else + ActiveRecord::Base.connection_db_config + end end if Rails.version < '6.1'