Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Active Support lazy load hooks #232

Merged
merged 1 commit into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 21 additions & 46 deletions lib/chrono_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

require 'active_record'

require 'chrono_model/chrono'
require 'chrono_model/conversions'
require 'chrono_model/patches'
require 'chrono_model/adapter'
require 'chrono_model/time_machine'
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
Expand All @@ -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
17 changes: 17 additions & 0 deletions lib/chrono_model/chrono.rb
Original file line number Diff line number Diff line change
@@ -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
9 changes: 9 additions & 0 deletions lib/chrono_model/db_console.rb
Original file line number Diff line number Diff line change
@@ -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
1 change: 0 additions & 1 deletion lib/chrono_model/patches.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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'
16 changes: 6 additions & 10 deletions lib/chrono_model/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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'
Expand Down