temporal_tables 0.7.1 → 1.0.2

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.
Files changed (60) 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 -7
  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.1.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 +93 -97
  27. data/lib/temporal_tables/temporal_adapter_six_oh.rb +187 -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 +65 -35
  33. data/spec/internal/app/models/broom.rb +2 -0
  34. data/spec/internal/app/models/cat.rb +5 -0
  35. data/spec/internal/app/models/cat_life.rb +5 -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 +28 -5
  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 +108 -39
  47. data/CHANGELOG.md +0 -73
  48. data/gemfiles/Gemfile.5.0.mysql +0 -16
  49. data/gemfiles/Gemfile.5.0.mysql.lock +0 -147
  50. data/gemfiles/Gemfile.5.0.pg +0 -16
  51. data/gemfiles/Gemfile.5.0.pg.lock +0 -147
  52. data/gemfiles/Gemfile.5.1.mysql.lock +0 -147
  53. data/gemfiles/Gemfile.5.1.pg +0 -16
  54. data/gemfiles/Gemfile.5.1.pg.lock +0 -147
  55. data/gemfiles/Gemfile.5.2.mysql +0 -16
  56. data/gemfiles/Gemfile.5.2.mysql.lock +0 -155
  57. data/gemfiles/Gemfile.5.2.pg.lock +0 -155
  58. data/lib/temporal_tables/join_extensions.rb +0 -20
  59. data/spec/extensions/combustion.rb +0 -9
  60. data/spec/internal/config/routes.rb +0 -3
@@ -1,39 +1,45 @@
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
- create_table temporal_name(table_name), options.merge(id: false, primary_key: "history_id", temporal_bypass: true) do |t|
30
- t.integer :id
31
- t.datetime :eff_from, :null => false, limit: 6
32
- t.datetime :eff_to, :null => false, limit: 6, :default => "9999-12-31"
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
36
+ t.datetime :eff_from, null: false, limit: 6
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'
33
41
 
34
- for c in columns(table_name)
35
- next if c.name == "id"
36
- t.send c.type, c.name, :limit => c.limit
42
+ t.send c.type, c.name, limit: c.limit
37
43
  end
38
44
  end
39
45
 
@@ -49,106 +55,108 @@ module TemporalTables
49
55
  end
50
56
 
51
57
  def remove_temporal_table(table_name)
52
- if table_exists?(temporal_name(table_name))
53
- drop_temporal_triggers table_name
54
- drop_table_without_temporal temporal_name(table_name)
55
- 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)
56
62
  end
57
63
 
58
- def drop_table(table_name, options = {})
59
- super table_name, options
64
+ def drop_table(table_name, **options)
65
+ super(table_name, **options)
60
66
 
61
- if table_exists?(temporal_name(table_name))
62
- super temporal_name(table_name), options
63
- end
67
+ super(temporal_name(table_name), **options) if table_exists?(temporal_name(table_name))
64
68
  end
65
69
 
66
70
  def rename_table(name, new_name)
67
- if table_exists?(temporal_name(name))
68
- drop_temporal_triggers name
69
- end
71
+ drop_temporal_triggers name if table_exists?(temporal_name(name))
70
72
 
71
73
  super name, new_name
72
74
 
73
- if table_exists?(temporal_name(name))
74
- super temporal_name(name), temporal_name(new_name)
75
- create_temporal_triggers new_name
76
- 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
77
79
  end
78
80
 
79
- def add_column(table_name, column_name, type, options = {})
80
- 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)
81
83
 
82
- if table_exists?(temporal_name(table_name))
83
- super temporal_name(table_name), column_name, type, options
84
- create_temporal_triggers table_name
85
- 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
86
88
  end
87
89
 
88
- def remove_column(table_name, *column_names)
89
- super table_name, *column_names
90
+ def remove_columns(table_name, *column_names, **options)
91
+ super(table_name, *column_names, **options)
90
92
 
91
- if table_exists?(temporal_name(table_name))
92
- super temporal_name(table_name), *column_names
93
- create_temporal_triggers table_name
94
- 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
95
97
  end
96
98
 
97
- def change_column(table_name, column_name, type, options = {})
98
- 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)
99
101
 
100
- if table_exists?(temporal_name(table_name))
101
- super temporal_name(table_name), column_name, type, options
102
- # Don't need to update triggers here...
103
- 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...
104
115
  end
105
116
 
106
117
  def rename_column(table_name, column_name, new_column_name)
107
- super table_name, column_name, new_column_name
118
+ super(table_name, column_name, new_column_name)
108
119
 
109
- if table_exists?(temporal_name(table_name))
110
- super temporal_name(table_name), column_name, new_column_name
111
- create_temporal_triggers table_name
112
- 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
113
124
  end
114
125
 
115
- def add_index(table_name, column_name, options = {})
116
- super table_name, column_name, options
126
+ def add_index(table_name, column_name, **options)
127
+ super(table_name, column_name, **options)
117
128
 
118
- if table_exists?(temporal_name(table_name))
119
- column_names = Array.wrap(column_name)
120
- idx_name = temporal_index_name(options[:name] || index_name(table_name, :column => column_names))
129
+ return unless table_exists?(temporal_name(table_name))
121
130
 
122
- super temporal_name(table_name), column_name, options.except(:unique).merge(name: idx_name)
123
- 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)
124
133
  end
125
134
 
126
- def remove_index(table_name, options = {})
127
- super table_name, options
135
+ def remove_index(table_name, column_name = nil, **options)
136
+ super(table_name, column_name, **options)
128
137
 
129
- if table_exists?(temporal_name(table_name))
130
- idx_name = temporal_index_name(index_name(table_name, options))
138
+ return unless table_exists?(temporal_name(table_name))
131
139
 
132
- super temporal_name(table_name), :name => idx_name
133
- end
140
+ idx_name = temporal_index_name(options[:name] || index_name_for_remove(table_name, column_name, options))
141
+ super temporal_name(table_name), column_name, name: idx_name
134
142
  end
135
143
 
136
- def create_temporal_indexes(table_name)
144
+ def create_temporal_indexes(table_name) # rubocop:disable Metrics/MethodLength
137
145
  indexes = ActiveRecord::Base.connection.indexes(table_name)
138
146
 
139
147
  indexes.each do |index|
140
148
  index_name = temporal_index_name(index.name)
141
149
 
142
- unless temporal_index_exists?(table_name, index_name)
143
- add_index(
144
- temporal_name(table_name),
145
- index.columns, {
146
- # exclude unique constraints for temporal tables
147
- :name => index_name,
148
- :length => index.lengths,
149
- :order => index.orders
150
- })
151
- end
150
+ next if temporal_index_exists?(table_name, index_name)
151
+
152
+ add_index(
153
+ temporal_name(table_name),
154
+ index.columns,
155
+ # exclude unique constraints for temporal tables
156
+ name: index_name,
157
+ length: index.lengths,
158
+ order: index.orders
159
+ )
152
160
  end
153
161
  end
154
162
 
@@ -156,33 +164,21 @@ module TemporalTables
156
164
  "#{table_name}_h"
157
165
  end
158
166
 
159
- def create_temporal_triggers(table_name)
160
- raise NotImplementedError, "create_temporal_triggers is not implemented"
167
+ def create_temporal_triggers(_table_name)
168
+ raise NotImplementedError, 'create_temporal_triggers is not implemented'
161
169
  end
162
170
 
163
- def drop_temporal_triggers(table_name)
164
- raise NotImplementedError, "drop_temporal_triggers is not implemented"
171
+ def drop_temporal_triggers(_table_name)
172
+ raise NotImplementedError, 'drop_temporal_triggers is not implemented'
165
173
  end
166
174
 
167
175
  # It's important not to increase the length of the returned string.
168
176
  def temporal_index_name(index_name)
169
- index_name.to_s.sub(/^index/, "ind_h").sub(/_ix(\d+)$/, '_hi\1')
177
+ index_name.to_s.sub(/^index/, 'ind_h').sub(/_ix(\d+)$/, '_hi\1')
170
178
  end
171
179
 
172
180
  def temporal_index_exists?(table_name, index_name)
173
- case Rails::VERSION::MAJOR
174
- when 5
175
- case Rails::VERSION::MINOR
176
- when 0
177
- index_name_exists?(temporal_name(table_name), index_name, false)
178
- else
179
- index_name_exists?(temporal_name(table_name), index_name)
180
- end
181
- when 6
182
- index_name_exists?(temporal_name(table_name), index_name)
183
- else
184
- raise "Rails version not supported"
185
- end
181
+ index_name_exists?(temporal_name(table_name), index_name)
186
182
  end
187
183
  end
188
184
  end
@@ -0,0 +1,187 @@
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
+ super(table_name, options)
140
+
141
+ return unless table_exists?(temporal_name(table_name))
142
+
143
+ idx_name = temporal_index_name(index_name_for_remove(table_name, options))
144
+ super temporal_name(table_name), name: idx_name
145
+ end
146
+
147
+ def create_temporal_indexes(table_name) # rubocop:disable Metrics/MethodLength
148
+ indexes = ActiveRecord::Base.connection.indexes(table_name)
149
+
150
+ indexes.each do |index|
151
+ index_name = temporal_index_name(index.name)
152
+
153
+ next if temporal_index_exists?(table_name, index_name)
154
+
155
+ add_index(
156
+ temporal_name(table_name),
157
+ index.columns,
158
+ # exclude unique constraints for temporal tables
159
+ name: index_name,
160
+ length: index.lengths,
161
+ order: index.orders
162
+ )
163
+ end
164
+ end
165
+
166
+ def temporal_name(table_name)
167
+ "#{table_name}_h"
168
+ end
169
+
170
+ def create_temporal_triggers(_table_name)
171
+ raise NotImplementedError, 'create_temporal_triggers is not implemented'
172
+ end
173
+
174
+ def drop_temporal_triggers(_table_name)
175
+ raise NotImplementedError, 'drop_temporal_triggers is not implemented'
176
+ end
177
+
178
+ # It's important not to increase the length of the returned string.
179
+ def temporal_index_name(index_name)
180
+ index_name.to_s.sub(/^index/, 'ind_h').sub(/_ix(\d+)$/, '_hi\1')
181
+ end
182
+
183
+ def temporal_index_exists?(table_name, index_name)
184
+ index_name_exists?(temporal_name(table_name), index_name)
185
+ end
186
+ end
187
+ 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.7.1"
4
+ VERSION = '1.0.2'
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