temporal_tables 0.8.0 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +53 -0
  3. data/.rubocop.yml +158 -0
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +5 -5
  6. data/Gemfile +2 -0
  7. data/README.md +15 -5
  8. data/Rakefile +7 -2
  9. data/config.ru +2 -0
  10. data/gemfiles/Gemfile.6.0.mysql.lock +84 -84
  11. data/gemfiles/Gemfile.6.0.pg.lock +103 -98
  12. data/gemfiles/Gemfile.6.1.mysql.lock +180 -0
  13. data/gemfiles/Gemfile.6.1.pg.lock +180 -0
  14. data/gemfiles/{Gemfile.5.2.mysql → Gemfile.7.0.mysql} +2 -2
  15. data/gemfiles/Gemfile.7.0.mysql.lock +173 -0
  16. data/gemfiles/{Gemfile.5.2.pg → Gemfile.7.0.pg} +1 -1
  17. data/gemfiles/Gemfile.7.0.pg.lock +173 -0
  18. data/lib/temporal_tables/arel_table.rb +10 -9
  19. data/lib/temporal_tables/association_extensions.rb +2 -0
  20. data/lib/temporal_tables/connection_adapters/mysql_adapter.rb +8 -3
  21. data/lib/temporal_tables/connection_adapters/postgresql_adapter.rb +5 -3
  22. data/lib/temporal_tables/history_hook.rb +8 -5
  23. data/lib/temporal_tables/preloader_extensions.rb +2 -0
  24. data/lib/temporal_tables/reflection_extensions.rb +11 -14
  25. data/lib/temporal_tables/relation_extensions.rb +11 -24
  26. data/lib/temporal_tables/temporal_adapter.rb +92 -101
  27. data/lib/temporal_tables/temporal_adapter_six_oh.rb +188 -0
  28. data/lib/temporal_tables/temporal_class.rb +29 -28
  29. data/lib/temporal_tables/version.rb +3 -1
  30. data/lib/temporal_tables/whodunnit.rb +5 -3
  31. data/lib/temporal_tables.rb +48 -33
  32. data/spec/basic_history_spec.rb +52 -43
  33. data/spec/internal/app/models/broom.rb +2 -0
  34. data/spec/internal/app/models/cat.rb +3 -1
  35. data/spec/internal/app/models/cat_life.rb +2 -0
  36. data/spec/internal/app/models/coven.rb +2 -0
  37. data/spec/internal/app/models/flying_machine.rb +2 -0
  38. data/spec/internal/app/models/person.rb +2 -0
  39. data/spec/internal/app/models/rocket_broom.rb +2 -0
  40. data/spec/internal/app/models/wart.rb +3 -1
  41. data/spec/internal/config/database.ci.yml +12 -0
  42. data/spec/internal/db/schema.rb +16 -9
  43. data/spec/spec_helper.rb +39 -5
  44. data/spec/support/database.rb +10 -6
  45. data/temporal_tables.gemspec +31 -18
  46. metadata +104 -35
  47. data/CHANGELOG.md +0 -73
  48. data/gemfiles/Gemfile.5.1.mysql +0 -16
  49. data/gemfiles/Gemfile.5.1.mysql.lock +0 -147
  50. data/gemfiles/Gemfile.5.1.pg +0 -16
  51. data/gemfiles/Gemfile.5.1.pg.lock +0 -147
  52. data/gemfiles/Gemfile.5.2.mysql.lock +0 -155
  53. data/gemfiles/Gemfile.5.2.pg.lock +0 -155
  54. data/lib/temporal_tables/join_extensions.rb +0 -20
  55. data/spec/extensions/combustion.rb +0 -9
  56. data/spec/internal/config/routes.rb +0 -3
@@ -1,40 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TemporalTables
2
- module TemporalAdapter
3
- def create_table(table_name, options = {}, &block)
4
+ module TemporalAdapter # rubocop:disable Metrics/ModuleLength
5
+ def create_table(table_name, **options, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
4
6
  if options[:temporal_bypass]
5
- super table_name, options, &block
7
+ super(table_name, **options, &block)
6
8
  else
7
9
  skip_table = TemporalTables.skipped_temporal_tables.include?(table_name.to_sym) || table_name.to_s =~ /_h$/
8
10
 
9
- super table_name, options do |t|
11
+ super(table_name, **options) do |t|
10
12
  block.call t
11
13
 
12
14
  if TemporalTables.add_updated_by_field && !skip_table
13
- updated_by_already_exists = t.columns.any? { |c| c.name == "updated_by" }
15
+ updated_by_already_exists = t.columns.any? { |c| c.name == 'updated_by' }
14
16
  if updated_by_already_exists
15
- puts "consider adding #{table_name} to TemporalTables skip_table"
17
+ puts "consider adding #{table_name} to TemporalTables skip_table" # rubocop:disable Rails/Output
16
18
  else
17
- t.column :updated_by, TemporalTables.updated_by_type
19
+ t.column(:updated_by, TemporalTables.updated_by_type)
18
20
  end
19
21
  end
20
22
  end
21
23
 
22
24
  if options[:temporal] || (TemporalTables.create_by_default && !skip_table)
23
- add_temporal_table table_name, options
25
+ add_temporal_table table_name, **options
24
26
  end
25
27
  end
26
28
  end
27
29
 
28
- def add_temporal_table(table_name, options = {})
29
- id = id_column(table_name)
30
-
31
- create_table temporal_name(table_name), options.merge(id: false, primary_key: "history_id", temporal_bypass: true) do |t|
32
- t.column :id, id.type
30
+ def add_temporal_table(table_name, **options) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
31
+ create_table(
32
+ temporal_name(table_name),
33
+ **options.merge(id: false, primary_key: 'history_id', temporal_bypass: true)
34
+ ) do |t|
35
+ t.column :id, options.fetch(:id, :integer) if options[:id] != false
33
36
  t.datetime :eff_from, null: false, limit: 6
34
- t.datetime :eff_to, null: false, limit: 6, default: "9999-12-31"
37
+ t.datetime :eff_to, null: false, limit: 6, default: '9999-12-31'
38
+
39
+ columns(table_name).each do |c|
40
+ next if c.name == 'id'
35
41
 
36
- for c in columns(table_name)
37
- next if c.name == "id"
38
42
  t.send c.type, c.name, limit: c.limit
39
43
  end
40
44
  end
@@ -51,106 +55,109 @@ module TemporalTables
51
55
  end
52
56
 
53
57
  def remove_temporal_table(table_name)
54
- if table_exists?(temporal_name(table_name))
55
- drop_temporal_triggers table_name
56
- drop_table_without_temporal temporal_name(table_name)
57
- end
58
+ return unless table_exists?(temporal_name(table_name))
59
+
60
+ drop_temporal_triggers table_name
61
+ drop_table_without_temporal temporal_name(table_name)
58
62
  end
59
63
 
60
- def drop_table(table_name, options = {})
61
- super table_name, options
64
+ def drop_table(table_name, **options)
65
+ super(table_name, **options)
62
66
 
63
- if table_exists?(temporal_name(table_name))
64
- super temporal_name(table_name), options
65
- end
67
+ super(temporal_name(table_name), **options) if table_exists?(temporal_name(table_name))
66
68
  end
67
69
 
68
70
  def rename_table(name, new_name)
69
- if table_exists?(temporal_name(name))
70
- drop_temporal_triggers name
71
- end
71
+ drop_temporal_triggers name if table_exists?(temporal_name(name))
72
72
 
73
73
  super name, new_name
74
74
 
75
- if table_exists?(temporal_name(name))
76
- super temporal_name(name), temporal_name(new_name)
77
- create_temporal_triggers new_name
78
- end
75
+ return unless table_exists?(temporal_name(name))
76
+
77
+ super(temporal_name(name), temporal_name(new_name))
78
+ create_temporal_triggers new_name
79
79
  end
80
80
 
81
- def add_column(table_name, column_name, type, options = {})
82
- super table_name, column_name, type, options
81
+ def add_column(table_name, column_name, type, **options)
82
+ super(table_name, column_name, type, **options)
83
83
 
84
- if table_exists?(temporal_name(table_name))
85
- super temporal_name(table_name), column_name, type, options
86
- create_temporal_triggers table_name
87
- end
84
+ return unless table_exists?(temporal_name(table_name))
85
+
86
+ super temporal_name(table_name), column_name, type, **options
87
+ create_temporal_triggers table_name
88
88
  end
89
89
 
90
- def remove_column(table_name, *column_names)
91
- super table_name, *column_names
90
+ def remove_columns(table_name, *column_names, **options)
91
+ super(table_name, *column_names, **options)
92
92
 
93
- if table_exists?(temporal_name(table_name))
94
- super temporal_name(table_name), *column_names
95
- create_temporal_triggers table_name
96
- end
93
+ return unless table_exists?(temporal_name(table_name))
94
+
95
+ super temporal_name(table_name), *column_names, **options
96
+ create_temporal_triggers table_name
97
97
  end
98
98
 
99
- def change_column(table_name, column_name, type, options = {})
100
- super table_name, column_name, type, options
99
+ def remove_column(table_name, column_name, type = nil, **options)
100
+ super(table_name, column_name, type, **options)
101
101
 
102
- if table_exists?(temporal_name(table_name))
103
- super temporal_name(table_name), column_name, type, options
104
- # Don't need to update triggers here...
105
- end
102
+ return unless table_exists?(temporal_name(table_name))
103
+
104
+ super temporal_name(table_name), column_name, type, **options
105
+ create_temporal_triggers table_name
106
+ end
107
+
108
+ def change_column(table_name, column_name, type, **options)
109
+ super(table_name, column_name, type, **options)
110
+
111
+ return unless table_exists?(temporal_name(table_name))
112
+
113
+ super temporal_name(table_name), column_name, type, **options
114
+ # Don't need to update triggers here...
106
115
  end
107
116
 
108
117
  def rename_column(table_name, column_name, new_column_name)
109
- super table_name, column_name, new_column_name
118
+ super(table_name, column_name, new_column_name)
110
119
 
111
- if table_exists?(temporal_name(table_name))
112
- super temporal_name(table_name), column_name, new_column_name
113
- create_temporal_triggers table_name
114
- end
120
+ return unless table_exists?(temporal_name(table_name))
121
+
122
+ super temporal_name(table_name), column_name, new_column_name
123
+ create_temporal_triggers table_name
115
124
  end
116
125
 
117
- def add_index(table_name, column_name, options = {})
118
- super table_name, column_name, options
126
+ def add_index(table_name, column_name, **options)
127
+ super(table_name, column_name, **options)
119
128
 
120
- if table_exists?(temporal_name(table_name))
121
- column_names = Array.wrap(column_name)
122
- idx_name = temporal_index_name(options[:name] || index_name(table_name, :column => column_names))
129
+ return unless table_exists?(temporal_name(table_name))
123
130
 
124
- super temporal_name(table_name), column_name, options.except(:unique).merge(name: idx_name)
125
- end
131
+ idx_name = temporal_index_name(options[:name] || index_name(table_name, column: column_name))
132
+ super temporal_name(table_name), column_name, **options.except(:unique).merge(name: idx_name)
126
133
  end
127
134
 
128
- def remove_index(table_name, options = {})
129
- super table_name, options
135
+ def remove_index(table_name, column_name = nil, **options)
136
+ original_index_name = index_name_for_remove(table_name, column_name, options)
137
+ super(table_name, column_name, **options)
130
138
 
131
- if table_exists?(temporal_name(table_name))
132
- idx_name = temporal_index_name(index_name(table_name, options))
139
+ return unless table_exists?(temporal_name(table_name))
133
140
 
134
- super temporal_name(table_name), :name => idx_name
135
- end
141
+ idx_name = temporal_index_name(options[:name] || original_index_name)
142
+ super temporal_name(table_name), column_name, name: idx_name
136
143
  end
137
144
 
138
- def create_temporal_indexes(table_name)
145
+ def create_temporal_indexes(table_name) # rubocop:disable Metrics/MethodLength
139
146
  indexes = ActiveRecord::Base.connection.indexes(table_name)
140
147
 
141
148
  indexes.each do |index|
142
149
  index_name = temporal_index_name(index.name)
143
150
 
144
- unless temporal_index_exists?(table_name, index_name)
145
- add_index(
146
- temporal_name(table_name),
147
- index.columns, {
148
- # exclude unique constraints for temporal tables
149
- :name => index_name,
150
- :length => index.lengths,
151
- :order => index.orders
152
- })
153
- end
151
+ next if temporal_index_exists?(table_name, index_name)
152
+
153
+ add_index(
154
+ temporal_name(table_name),
155
+ index.columns,
156
+ # exclude unique constraints for temporal tables
157
+ name: index_name,
158
+ length: index.lengths,
159
+ order: index.orders
160
+ )
154
161
  end
155
162
  end
156
163
 
@@ -158,37 +165,21 @@ module TemporalTables
158
165
  "#{table_name}_h"
159
166
  end
160
167
 
161
- def create_temporal_triggers(table_name)
162
- raise NotImplementedError, "create_temporal_triggers is not implemented"
168
+ def create_temporal_triggers(_table_name)
169
+ raise NotImplementedError, 'create_temporal_triggers is not implemented'
163
170
  end
164
171
 
165
- def drop_temporal_triggers(table_name)
166
- raise NotImplementedError, "drop_temporal_triggers is not implemented"
172
+ def drop_temporal_triggers(_table_name)
173
+ raise NotImplementedError, 'drop_temporal_triggers is not implemented'
167
174
  end
168
175
 
169
176
  # It's important not to increase the length of the returned string.
170
177
  def temporal_index_name(index_name)
171
- index_name.to_s.sub(/^index/, "ind_h").sub(/_ix(\d+)$/, '_hi\1')
178
+ index_name.to_s.sub(/^index/, 'ind_h').sub(/_ix(\d+)$/, '_hi\1')
172
179
  end
173
180
 
174
181
  def temporal_index_exists?(table_name, index_name)
175
- case Rails::VERSION::MAJOR
176
- when 5
177
- case Rails::VERSION::MINOR
178
- when 0
179
- index_name_exists?(temporal_name(table_name), index_name, false)
180
- else
181
- index_name_exists?(temporal_name(table_name), index_name)
182
- end
183
- when 6
184
- index_name_exists?(temporal_name(table_name), index_name)
185
- else
186
- raise "Rails version not supported"
187
- end
188
- end
189
-
190
- def id_column(table_name)
191
- columns(table_name).detect { |c| c.name == "id" }
182
+ index_name_exists?(temporal_name(table_name), index_name)
192
183
  end
193
184
  end
194
185
  end
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TemporalTables
4
+ # The main difference here is the add_index method, which still uses
5
+ # the old options={} syntax
6
+ module TemporalAdapterSixOh # rubocop:disable Metrics/ModuleLength
7
+ def create_table(table_name, **options, &block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
8
+ if options[:temporal_bypass]
9
+ super(table_name, **options, &block)
10
+ else
11
+ skip_table = TemporalTables.skipped_temporal_tables.include?(table_name.to_sym) || table_name.to_s =~ /_h$/
12
+
13
+ super(table_name, **options) do |t|
14
+ block.call t
15
+
16
+ if TemporalTables.add_updated_by_field && !skip_table
17
+ updated_by_already_exists = t.columns.any? { |c| c.name == 'updated_by' }
18
+ if updated_by_already_exists
19
+ puts "consider adding #{table_name} to TemporalTables skip_table" # rubocop:disable Rails/Output
20
+ else
21
+ t.column(:updated_by, TemporalTables.updated_by_type)
22
+ end
23
+ end
24
+ end
25
+
26
+ if options[:temporal] || (TemporalTables.create_by_default && !skip_table)
27
+ add_temporal_table table_name, **options
28
+ end
29
+ end
30
+ end
31
+
32
+ def add_temporal_table(table_name, **options) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
33
+ create_table(
34
+ temporal_name(table_name),
35
+ **options.merge(id: false, primary_key: 'history_id', temporal_bypass: true)
36
+ ) do |t|
37
+ t.column :id, options.fetch(:id, :integer) if options[:id] != false
38
+ t.datetime :eff_from, null: false, limit: 6
39
+ t.datetime :eff_to, null: false, limit: 6, default: '9999-12-31'
40
+
41
+ columns(table_name).each do |c|
42
+ next if c.name == 'id'
43
+
44
+ t.send c.type, c.name, limit: c.limit
45
+ end
46
+ end
47
+
48
+ if TemporalTables.add_updated_by_field && !column_exists?(table_name, :updated_by)
49
+ change_table table_name do |t|
50
+ t.column :updated_by, TemporalTables.updated_by_type
51
+ end
52
+ end
53
+
54
+ add_index temporal_name(table_name), [:id, :eff_to]
55
+ create_temporal_triggers table_name
56
+ create_temporal_indexes table_name
57
+ end
58
+
59
+ def remove_temporal_table(table_name)
60
+ return unless table_exists?(temporal_name(table_name))
61
+
62
+ drop_temporal_triggers table_name
63
+ drop_table_without_temporal temporal_name(table_name)
64
+ end
65
+
66
+ def drop_table(table_name, **options)
67
+ super(table_name, **options)
68
+
69
+ super(temporal_name(table_name), **options) if table_exists?(temporal_name(table_name))
70
+ end
71
+
72
+ def rename_table(name, new_name)
73
+ drop_temporal_triggers name if table_exists?(temporal_name(name))
74
+
75
+ super name, new_name
76
+
77
+ return unless table_exists?(temporal_name(name))
78
+
79
+ super(temporal_name(name), temporal_name(new_name))
80
+ create_temporal_triggers new_name
81
+ end
82
+
83
+ def add_column(table_name, column_name, type, **options)
84
+ super(table_name, column_name, type, **options)
85
+
86
+ return unless table_exists?(temporal_name(table_name))
87
+
88
+ super temporal_name(table_name), column_name, type, **options
89
+ create_temporal_triggers table_name
90
+ end
91
+
92
+ def remove_columns(table_name, *column_names, **options)
93
+ super(table_name, *column_names, **options)
94
+
95
+ return unless table_exists?(temporal_name(table_name))
96
+
97
+ super temporal_name(table_name), *column_names, **options
98
+ create_temporal_triggers table_name
99
+ end
100
+
101
+ def remove_column(table_name, column_name, type = nil, **options)
102
+ super(table_name, column_name, type, **options)
103
+
104
+ return unless table_exists?(temporal_name(table_name))
105
+
106
+ super temporal_name(table_name), column_name, type, **options
107
+ create_temporal_triggers table_name
108
+ end
109
+
110
+ def change_column(table_name, column_name, type, **options)
111
+ super(table_name, column_name, type, **options)
112
+
113
+ return unless table_exists?(temporal_name(table_name))
114
+
115
+ super temporal_name(table_name), column_name, type, **options
116
+ # Don't need to update triggers here...
117
+ end
118
+
119
+ def rename_column(table_name, column_name, new_column_name)
120
+ super(table_name, column_name, new_column_name)
121
+
122
+ return unless table_exists?(temporal_name(table_name))
123
+
124
+ super temporal_name(table_name), column_name, new_column_name
125
+ create_temporal_triggers table_name
126
+ end
127
+
128
+ def add_index(table_name, column_name, options = {})
129
+ super(table_name, column_name, options)
130
+
131
+ return unless table_exists?(temporal_name(table_name))
132
+
133
+ column_names = Array.wrap(column_name)
134
+ idx_name = temporal_index_name(options[:name] || index_name(table_name, column: column_names))
135
+ super temporal_name(table_name), column_name, options.except(:unique).merge(name: idx_name)
136
+ end
137
+
138
+ def remove_index(table_name, options = {})
139
+ original_index_name = index_name_for_remove(table_name, options)
140
+ super(table_name, options)
141
+
142
+ return unless table_exists?(temporal_name(table_name))
143
+
144
+ idx_name = temporal_index_name(original_index_name)
145
+ super temporal_name(table_name), name: idx_name
146
+ end
147
+
148
+ def create_temporal_indexes(table_name) # rubocop:disable Metrics/MethodLength
149
+ indexes = ActiveRecord::Base.connection.indexes(table_name)
150
+
151
+ indexes.each do |index|
152
+ index_name = temporal_index_name(index.name)
153
+
154
+ next if temporal_index_exists?(table_name, index_name)
155
+
156
+ add_index(
157
+ temporal_name(table_name),
158
+ index.columns,
159
+ # exclude unique constraints for temporal tables
160
+ name: index_name,
161
+ length: index.lengths,
162
+ order: index.orders
163
+ )
164
+ end
165
+ end
166
+
167
+ def temporal_name(table_name)
168
+ "#{table_name}_h"
169
+ end
170
+
171
+ def create_temporal_triggers(_table_name)
172
+ raise NotImplementedError, 'create_temporal_triggers is not implemented'
173
+ end
174
+
175
+ def drop_temporal_triggers(_table_name)
176
+ raise NotImplementedError, 'drop_temporal_triggers is not implemented'
177
+ end
178
+
179
+ # It's important not to increase the length of the returned string.
180
+ def temporal_index_name(index_name)
181
+ index_name.to_s.sub(/^index/, 'ind_h').sub(/_ix(\d+)$/, '_hi\1')
182
+ end
183
+
184
+ def temporal_index_exists?(table_name, index_name)
185
+ index_name_exists?(temporal_name(table_name), index_name)
186
+ end
187
+ end
188
+ end
@@ -1,14 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TemporalTables
2
4
  # This is mixed into all History classes.
3
5
  module TemporalClass
4
- def self.included(base)
6
+ def self.included(base) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
5
7
  base.class_eval do
6
8
  base.extend ClassMethods
7
9
 
8
- self.table_name += "_h"
10
+ self.table_name += '_h'
9
11
 
10
12
  cattr_accessor :visited_associations
11
- @@visited_associations = []
13
+ @visited_associations = []
12
14
 
13
15
  # The at_value field stores the time from the query that yielded
14
16
  # this record.
@@ -23,26 +25,27 @@ module TemporalTables
23
25
  # Iterates all associations, makes sure their history classes are
24
26
  # created and initialized, and modifies the associations to point
25
27
  # to the target classes' history classes.
26
- def self.temporalize_associations!
28
+ def self.temporalize_associations! # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
27
29
  reflect_on_all_associations.dup.each do |association|
28
- unless @@visited_associations.include?(association.name) || association.options[:polymorphic]
29
- @@visited_associations << association.name
30
-
31
- # Calling .history here will ensure that the history class
32
- # for this association is created and initialized
33
- clazz = association.class_name.constantize.history
34
-
35
- # Recreate the association, updating it to point at the
36
- # history class. The foreign key is explicitly set since it's
37
- # inferred from the class_name, but shouldn't be in this case.
38
- send(association.macro, association.name,
39
- association.options.merge(
40
- class_name: clazz.name,
41
- foreign_key: association.foreign_key,
42
- primary_key: clazz.orig_class.primary_key
43
- )
30
+ next if @visited_associations.include?(association.name) || association.options[:polymorphic]
31
+
32
+ @visited_associations << association.name
33
+
34
+ # Calling .history here will ensure that the history class
35
+ # for this association is created and initialized
36
+ clazz = association.class_name.constantize.history
37
+
38
+ # Recreate the association, updating it to point at the
39
+ # history class. The foreign key is explicitly set since it's
40
+ # inferred from the class_name, but shouldn't be in this case.
41
+ send(
42
+ association.macro, association.name,
43
+ **association.options.merge(
44
+ class_name: clazz.name,
45
+ foreign_key: association.foreign_key,
46
+ primary_key: clazz.orig_class.primary_key
44
47
  )
45
- end
48
+ )
46
49
  end
47
50
  end
48
51
  end
@@ -50,11 +53,11 @@ module TemporalTables
50
53
 
51
54
  module STIWithHistory
52
55
  def sti_name
53
- super.sub /History$/, ""
56
+ super.sub(/History$/, '')
54
57
  end
55
58
 
56
59
  def find_sti_class(type_name)
57
- type_name += "History" unless type_name =~ /History\Z/
60
+ type_name += 'History' unless type_name =~ /History\Z/
58
61
 
59
62
  begin
60
63
  super
@@ -66,12 +69,10 @@ module TemporalTables
66
69
 
67
70
  module ClassMethods
68
71
  def orig_class
69
- name.sub(/History$/, "").constantize
72
+ name.sub(/History$/, '').constantize
70
73
  end
71
74
 
72
- def descends_from_active_record?
73
- superclass.descends_from_active_record?
74
- end
75
+ delegate :descends_from_active_record?, to: :superclass
75
76
 
76
77
  def build_temporal_constraint(at_value)
77
78
  arel_table[:eff_to].gteq(at_value).and(
@@ -89,7 +90,7 @@ module TemporalTables
89
90
  end
90
91
 
91
92
  def orig_obj
92
- @orig_obj ||= orig_class.find_by_id orig_id
93
+ @orig_obj ||= orig_class.find_by id: orig_id
93
94
  end
94
95
 
95
96
  def prev
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TemporalTables
2
- VERSION = "0.8.0"
4
+ VERSION = '1.0.3'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TemporalTables
2
4
  module Whodunnit
3
5
  def self.included(base)
@@ -10,9 +12,9 @@ module TemporalTables
10
12
 
11
13
  module InstanceMethods
12
14
  def set_updated_by
13
- if TemporalTables.updated_by_proc && respond_to?(:updated_by)
14
- self.updated_by = TemporalTables.updated_by_proc.call(self)
15
- end
15
+ return unless TemporalTables.updated_by_proc && respond_to?(:updated_by)
16
+
17
+ self.updated_by = TemporalTables.updated_by_proc.call(self)
16
18
  end
17
19
  end
18
20
  end