From 59b14a488c6319749ad5bb2c727ec4337625a733 Mon Sep 17 00:00:00 2001 From: Geremia Taglialatela Date: Fri, 20 May 2022 10:21:40 +0200 Subject: [PATCH] Fix issue with through associations Fix #163 --- lib/chrono_model.rb | 4 ++++ lib/chrono_model/patches/preloader.rb | 16 ++++++++++++++++ spec/chrono_model/time_machine/as_of_spec.rb | 2 ++ 3 files changed, 22 insertions(+) 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..2d27929b 100644 --- a/lib/chrono_model/patches/preloader.rb +++ b/lib/chrono_model/patches/preloader.rb @@ -75,6 +75,22 @@ 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 + + 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..8d49bd0e 100644 --- a/spec/chrono_model/time_machine/as_of_spec.rb +++ b/spec/chrono_model/time_machine/as_of_spec.rb @@ -143,6 +143,8 @@ 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(: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' }