temporal_tables 0.7.1 → 1.0.2

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