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 +4 -4
- data/lib/chrono_model/patches.rb +39 -22
- data/lib/chrono_model/version.rb +1 -1
- data/spec/support/helpers.rb +2 -2
- data/spec/time_machine_spec.rb +5 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d582aa6350f8fac1d88f06a216447a309215479b
|
4
|
+
data.tar.gz: aaabf96f89bb5aad1af0e6f2425978ac484b855d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c5b541b0e8dfed9958e4ecab0b49adafeee077f7e8aca27f3d85e356cfa282f8247d890e0b06751d18da1d83c02570ff1dc6492e7fe404dd49d3c35d7a3eb74
|
7
|
+
data.tar.gz: df5f7d097d783efe86bc8b05d4d9736a81cab3222fd1f291e7e7f3101224b9f2a4d47c6b5789f222b7bbfbd97929ac6b386b7b33a9f17227c6d425ff2de9735c
|
data/lib/chrono_model/patches.rb
CHANGED
@@ -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 =
|
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
|
-
|
188
|
-
|
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
|
data/lib/chrono_model/version.rb
CHANGED
data/spec/support/helpers.rb
CHANGED
@@ -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::
|
126
|
+
include ChronoModel::TimeMachine
|
127
127
|
|
128
128
|
belongs_to :bar
|
129
129
|
|
data/spec/time_machine_spec.rb
CHANGED
@@ -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.
|
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-
|
12
|
+
date: 2017-09-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|