lib/chrono_model/patches/preloader.rb in chrono_model-1.2.2 vs lib/chrono_model/patches/preloader.rb in chrono_model-2.0.0

- old
+ new

@@ -1,20 +1,28 @@ +# frozen_string_literal: true + module ChronoModel module Patches - # Patches ActiveRecord::Associations::Preloader to add support for # temporal associations. This is tying itself to Rails internals # and it is ugly :-(. # module Preloader - attr_reader :options + attr_reader :chronomodel_options # We overwrite the initializer in order to pass the +as_of_time+ # parameter above in the build_preloader # - def initialize(options = {}) - @options = options.freeze + def initialize(**options) + @chronomodel_options = options.extract!(:as_of_time, :model) + options[:scope] = chronomodel_scope(options[:scope]) if options.key?(:scope) + + if options.empty? + super() + else + super(**options) + end end # Patches the AR Preloader (lib/active_record/associations/preloader.rb) # in order to carry around the +as_of_time+ of the original invocation. # @@ -35,18 +43,24 @@ # For `:through` associations, the +given_preload_scope+ is already a # +Relation+, that already has the +as_of_time+ getters and setters, # so we use it directly. # def preload(records, associations, given_preload_scope = nil) - if options[:as_of_time] - preload_scope = given_preload_scope || - ChronoModel::Patches::AsOfTimeRelation.new(options[:model]) + super(records, associations, chronomodel_scope(given_preload_scope)) + end - preload_scope.as_of_time!(options[:as_of_time]) + private + + def chronomodel_scope(given_preload_scope) + preload_scope = given_preload_scope + + if chronomodel_options[:as_of_time] + preload_scope ||= ChronoModel::Patches::AsOfTimeRelation.new(chronomodel_options[:model]) + preload_scope.as_of_time!(chronomodel_options[:as_of_time]) end - super records, associations, preload_scope + preload_scope end module Association # Builds the preloader scope taking into account a potential # +as_of_time+ passed down the call chain starting at the @@ -57,12 +71,28 @@ if preload_scope.try(:as_of_time) scope = scope.as_of(preload_scope.as_of_time) end - return scope + scope end end - end + module ThroughAssociation + # Builds the preloader scope taking into account a potential + # +as_of_time+ passed down the call chain starting at the + # end user invocation. + # + def through_scope + scope = super + return unless scope # Rails 5.2 may not return a scope + + if preload_scope.try(:as_of_time) + scope = scope.as_of(preload_scope.as_of_time) + end + + scope + end + end + end end end