diff --git a/lib/chrono_model.rb b/lib/chrono_model.rb index b3a8e96c..ff8a59b7 100644 --- a/lib/chrono_model.rb +++ b/lib/chrono_model.rb @@ -69,6 +69,10 @@ def chrono? prepend ChronoModel::Patches::Preloader::Association end +ActiveRecord::Associations::Preloader::ThroughAssociation.instance_eval do + prepend ChronoModel::Patches::Preloader::ThroughAssociation +end + if defined?(Rails::DBConsole) Rails::DBConsole.instance_eval do if Rails.version < '6.1' diff --git a/lib/chrono_model/patches/preloader.rb b/lib/chrono_model/patches/preloader.rb index 4de25ea5..853e5888 100644 --- a/lib/chrono_model/patches/preloader.rb +++ b/lib/chrono_model/patches/preloader.rb @@ -75,6 +75,23 @@ def build_scope return scope 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 diff --git a/spec/chrono_model/time_machine/as_of_spec.rb b/spec/chrono_model/time_machine/as_of_spec.rb index bb22e107..3c6655d1 100644 --- a/spec/chrono_model/time_machine/as_of_spec.rb +++ b/spec/chrono_model/time_machine/as_of_spec.rb @@ -143,6 +143,9 @@ it { expect(Foo.as_of($t.foo.ts[0]).includes(:bars, :sub_bars).first.sub_bars.first).to be nil } it { expect(Foo.as_of($t.foo.ts[1]).includes(:bars, :sub_bars).first.sub_bars.first).to be nil } + it { expect(Foo.as_of($t.bar.ts[0]).includes(:sub_bars).first.bars.first.sub_bars.first).to be nil } + it { expect(Foo.as_of($t.subbar.ts[0]).includes(:sub_bars).first.bars.first.sub_bars.first.name).to eq 'sub-bar' } + it { expect(Foo.as_of($t.subbar.ts[0]).includes(:bars, :sub_bars).first.sub_bars.first.name).to eq 'sub-bar' } it { expect(Foo.as_of($t.subbar.ts[1]).includes(:bars, :sub_bars).first.sub_bars.first.name).to eq 'bar sub-bar' } it { expect(Foo.as_of($t.subbar.ts[2]).includes(:bars, :sub_bars).first.sub_bars.first.name).to eq 'sub-bar sub-bar' }