chrono_model 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6372b41af69ba073bf8d6ea27f34c238ce3c1426
4
- data.tar.gz: 9bda73df3fa2d169da83fedd4d499521745a61b8
3
+ metadata.gz: d582aa6350f8fac1d88f06a216447a309215479b
4
+ data.tar.gz: aaabf96f89bb5aad1af0e6f2425978ac484b855d
5
5
  SHA512:
6
- metadata.gz: a04bfe04096c15f977c0972458e53508c81bccbf84b81df79e990f3174152af5f788f1564acf27ace77e3721ba9717a30ec8e5d68f813aaa2761528bed57da52
7
- data.tar.gz: 66289e54ef6511b1ff005705386585f82ce5571a99763b37d522d1208dcd87c738c7a2b2d004e205ed5438ff53d28cf8cc076bf29eb5657be318f326953efd1b
6
+ metadata.gz: 0c5b541b0e8dfed9958e4ecab0b49adafeee077f7e8aca27f3d85e356cfa282f8247d890e0b06751d18da1d83c02570ff1dc6492e7fe404dd49d3c35d7a3eb74
7
+ data.tar.gz: df5f7d097d783efe86bc8b05d4d9736a81cab3222fd1f291e7e7f3101224b9f2a4d47c6b5789f222b7bbfbd97929ac6b386b7b33a9f17227c6d425ff2de9735c
@@ -23,6 +23,33 @@ module ChronoModel
23
23
  end
24
24
  end
25
25
 
26
+ # This class supports the AR 4.2 code that expects to receive an
27
+ # Arel::Table as the left join node. We need to replace the node
28
+ # with a virtual table that fetches from the history at a given
29
+ # point in time, we replace the join node with a SqlLiteral node
30
+ # that does not respond to the methods that AR expects.
31
+ #
32
+ # This class provides AR with an object implementing the methods
33
+ # it expects, yet producing SQL that fetches from history tables
34
+ # as-of-time.
35
+ #
36
+ class JoinNode < Arel::Nodes::SqlLiteral
37
+ attr_reader :name, :table_name, :table_alias, :as_of_time
38
+
39
+ def initialize(join_node, history_model, as_of_time)
40
+ @name = join_node.table_name
41
+ @table_name = join_node.table_name
42
+ @table_alias = join_node.table_alias
43
+
44
+ @as_of_time = as_of_time
45
+
46
+ virtual_table = history_model.
47
+ virtual_table_at(@as_of_time, @table_alias || @table_name)
48
+
49
+ super(virtual_table)
50
+ end
51
+ end
52
+
26
53
  module Relation
27
54
  include AsOfTimeHolder
28
55
 
@@ -44,13 +71,15 @@ module ChronoModel
44
71
  super.tap do |arel|
45
72
 
46
73
  arel.join_sources.each do |join|
74
+ # This case happens with nested includes, where the below
75
+ # code has already replaced the join.left with a JoinNode.
76
+ #
77
+ next if join.left.respond_to?(:as_of_time)
78
+
47
79
  model = TimeMachine.chrono_models[join.left.table_name]
48
80
  next unless model
49
81
 
50
- join.left = Arel::Nodes::SqlLiteral.new(
51
- model.history.virtual_table_at(@_as_of_time,
52
- join.left.table_alias || join.left.table_name)
53
- )
82
+ join.left = JoinNode.new(join.left, model.history, @_as_of_time)
54
83
  end
55
84
 
56
85
  end
@@ -180,27 +209,15 @@ module ChronoModel
180
209
  scope = scope.from(klass.history.virtual_table_at(owner.as_of_time))
181
210
  elsif respond_to?(:through_reflection) && through_reflection.klass.chrono?
182
211
 
183
- # For through associations, replace the joined table name instead.
212
+ # For through associations, replace the joined table name instead
213
+ # with a virtual table that selects records from the history at
214
+ # the given +as_of_time+.
184
215
  #
185
216
  scope.join_sources.each do |join|
186
217
  if join.left.name == through_reflection.klass.table_name
187
- v_table = through_reflection.klass.history.virtual_table_at(
188
- owner.as_of_time, join.left.table_alias || join.left.table_name)
189
-
190
- # avoid problems in Rails when code down the line expects the
191
- # join.left to respond to the following methods. we modify
192
- # the instance of SqlLiteral to do just that.
193
- table_name = join.left.table_name
194
- table_alias = join.left.table_alias
195
- join.left = Arel::Nodes::SqlLiteral.new(v_table)
196
-
197
- class << join.left
198
- attr_accessor :name, :table_name, :table_alias
199
- end
200
-
201
- join.left.name = table_name
202
- join.left.table_name = table_name
203
- join.left.table_alias = table_alias
218
+ history_model = through_reflection.klass.history
219
+
220
+ join.left = JoinNode.new(join.left, history_model, owner.as_of_time)
204
221
  end
205
222
  end
206
223
  end
@@ -1,3 +1,3 @@
1
1
  module ChronoModel
2
- VERSION = "0.11.0"
2
+ VERSION = "0.11.1"
3
3
  end
@@ -74,7 +74,7 @@ module ChronoTest::Helpers
74
74
  t.references :foo
75
75
  end
76
76
 
77
- adapter.create_table 'sub_bars' do |t|
77
+ adapter.create_table 'sub_bars', :temporal => true do |t|
78
78
  t.string :name
79
79
  t.references :bar
80
80
  end
@@ -123,7 +123,7 @@ module ChronoTest::Helpers
123
123
  end
124
124
 
125
125
  class ::SubBar < ActiveRecord::Base
126
- include ChronoModel::TimeGate
126
+ include ChronoModel::TimeMachine
127
127
 
128
128
  belongs_to :bar
129
129
 
@@ -85,7 +85,8 @@ describe ChronoModel::TimeMachine do
85
85
  'foos' => Foo::History,
86
86
  'defoos' => Defoo::History,
87
87
  'bars' => Bar::History,
88
- 'elements' => Element::History
88
+ 'elements' => Element::History,
89
+ 'sub_bars' => SubBar::History,
89
90
  ) }
90
91
  end
91
92
 
@@ -183,6 +184,9 @@ describe ChronoModel::TimeMachine do
183
184
  it { expect(Bar.as_of(bar.ts[2]).includes(foo: :sub_bars).first.foo.name).to eq 'new foo' }
184
185
  it { expect(Bar.as_of(bar.ts[3]).includes(foo: :sub_bars).first.foo.name).to eq 'new foo' }
185
186
 
187
+ it { expect(Foo.as_of(foo.ts[0]).includes(bars: :sub_bars).first.sub_bars.count).to eq 0 }
188
+ it { expect(Foo.as_of(foo.ts[1]).includes(bars: :sub_bars).first.sub_bars.count).to eq 0 }
189
+ it { expect(Foo.as_of(foo.ts[2]).includes(bars: :sub_bars).first.sub_bars.count).to eq 1 }
186
190
  end
187
191
 
188
192
  it 'doesn\'t raise RecordNotFound when no history records are found' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chrono_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcello Barnaba
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-09-08 00:00:00.000000000 Z
12
+ date: 2017-09-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord