chrono_model 0.11.0 → 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|