historiographer 4.1.14 → 4.1.16
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/.document +5 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.standalone_migrations +6 -0
- data/Gemfile +33 -0
- data/Gemfile.lock +341 -0
- data/Guardfile +4 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/historiographer-4.1.12.gem +0 -0
- data/historiographer-4.1.13.gem +0 -0
- data/historiographer-4.1.14.gem +0 -0
- data/historiographer.gemspec +144 -0
- data/init.rb +18 -0
- data/instructions/implementation.md +282 -0
- data/instructions/todo.md +96 -0
- data/lib/historiographer/history.rb +1 -7
- data/lib/historiographer/version.rb +1 -1
- data/spec/db/database.yml +27 -0
- data/spec/db/migrate/20161121212228_create_posts.rb +19 -0
- data/spec/db/migrate/20161121212229_create_post_histories.rb +10 -0
- data/spec/db/migrate/20161121212230_create_authors.rb +13 -0
- data/spec/db/migrate/20161121212231_create_author_histories.rb +10 -0
- data/spec/db/migrate/20161121212232_create_users.rb +9 -0
- data/spec/db/migrate/20171011194624_create_safe_posts.rb +19 -0
- data/spec/db/migrate/20171011194715_create_safe_post_histories.rb +9 -0
- data/spec/db/migrate/20191024142304_create_thing_with_compound_index.rb +10 -0
- data/spec/db/migrate/20191024142352_create_thing_with_compound_index_history.rb +11 -0
- data/spec/db/migrate/20191024203106_create_thing_without_history.rb +7 -0
- data/spec/db/migrate/20221018204220_create_silent_posts.rb +21 -0
- data/spec/db/migrate/20221018204255_create_silent_post_histories.rb +9 -0
- data/spec/db/migrate/20241109182017_create_comments.rb +13 -0
- data/spec/db/migrate/20241109182020_create_comment_histories.rb +9 -0
- data/spec/db/migrate/20241118000000_add_type_to_posts.rb +6 -0
- data/spec/db/migrate/20241118000001_add_type_to_post_histories.rb +5 -0
- data/spec/db/migrate/20241118000002_create_ml_models.rb +19 -0
- data/spec/db/migrate/20241118000003_create_easy_ml_columns.rb +17 -0
- data/spec/db/migrate/20241119000000_create_datasets.rb +17 -0
- data/spec/db/schema.rb +308 -0
- data/spec/factories/post.rb +7 -0
- data/spec/historiographer_spec.rb +918 -0
- data/spec/models/application_record.rb +3 -0
- data/spec/models/author.rb +5 -0
- data/spec/models/author_history.rb +4 -0
- data/spec/models/comment.rb +5 -0
- data/spec/models/comment_history.rb +5 -0
- data/spec/models/dataset.rb +6 -0
- data/spec/models/dataset_history.rb +4 -0
- data/spec/models/easy_ml/column.rb +7 -0
- data/spec/models/easy_ml/column_history.rb +6 -0
- data/spec/models/easy_ml/encrypted_column.rb +10 -0
- data/spec/models/easy_ml/encrypted_column_history.rb +6 -0
- data/spec/models/ml_model.rb +6 -0
- data/spec/models/ml_model_history.rb +4 -0
- data/spec/models/post.rb +45 -0
- data/spec/models/post_history.rb +8 -0
- data/spec/models/private_post.rb +12 -0
- data/spec/models/private_post_history.rb +4 -0
- data/spec/models/safe_post.rb +5 -0
- data/spec/models/safe_post_history.rb +5 -0
- data/spec/models/silent_post.rb +3 -0
- data/spec/models/silent_post_history.rb +4 -0
- data/spec/models/thing_with_compound_index.rb +3 -0
- data/spec/models/thing_with_compound_index_history.rb +4 -0
- data/spec/models/thing_without_history.rb +2 -0
- data/spec/models/user.rb +2 -0
- data/spec/models/xgboost.rb +10 -0
- data/spec/models/xgboost_history.rb +4 -0
- data/spec/spec_helper.rb +105 -0
- metadata +70 -31
@@ -0,0 +1,282 @@
|
|
1
|
+
# Single Table Inheritance (STI) Implementation for Historiographer
|
2
|
+
|
3
|
+
You are assisting with a Rails gem called Historiographer. Your role is to make precise, surgical edits to the codebase based on specific tasks. The project has a complex architecture with interdependent components, so caution is required.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
This document outlines the steps needed to properly implement Single Table Inheritance (STI) for the Historiographer gem, following Rails best practices. The current implementation has a complex method forwarding mechanism that can lead to subtle bugs. We need to refactor this to use a clean, standard Rails STI approach within separate inheritance hierarchies.
|
8
|
+
|
9
|
+
## Current State Analysis
|
10
|
+
|
11
|
+
The current implementation has the following issues:
|
12
|
+
|
13
|
+
1. History classes implement a complex method delegation approach using `method_missing` and dynamic method definition
|
14
|
+
2. STI is partially implemented but doesn't correctly handle the inheritance hierarchy within history classes
|
15
|
+
3. The `type` column isn't properly set or managed according to Rails STI conventions
|
16
|
+
4. Method delegation between original and history models is overly complex and error-prone
|
17
|
+
|
18
|
+
## Implementation Requirements
|
19
|
+
|
20
|
+
1. User can define a `type` for their class, and that will be used to identify the STI class
|
21
|
+
2. The `type` should be a string, and the default value should be the class name
|
22
|
+
3. When a user creates a new instance, the `type` should be set to the class name automatically
|
23
|
+
4. STI subclasses should automatically inherit from their parent class
|
24
|
+
5. History classes should maintain a parallel inheritance hierarchy to original classes
|
25
|
+
6. When finding a history instance, it should automatically instantiate the correct subclass based on `type`
|
26
|
+
7. Implement clean method delegation from history classes to original models
|
27
|
+
|
28
|
+
## Implementation Approach: STI Within History Models
|
29
|
+
|
30
|
+
We will implement STI separately within original models and history models, maintaining two parallel inheritance hierarchies:
|
31
|
+
|
32
|
+
1. **Original Models Hierarchy**: `PrivatePost < Post < ActiveRecord::Base`
|
33
|
+
2. **History Models Hierarchy**: `PrivatePostHistory < PostHistory < ActiveRecord::Base`
|
34
|
+
|
35
|
+
This approach follows Rails conventions within each table while providing a clean way to implement method delegation between related models.
|
36
|
+
|
37
|
+
## Implementation Steps
|
38
|
+
|
39
|
+
### 1. Update `Historiographer::History` Module
|
40
|
+
|
41
|
+
#### Changes Required:
|
42
|
+
|
43
|
+
- Implement a clean method delegation system using `method_missing`
|
44
|
+
- Support proper STI inheritance within history models
|
45
|
+
- Ensure history classes correctly set and manage their `type` column
|
46
|
+
- Maintain table separation between original and history models
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
module Historiographer
|
50
|
+
module History
|
51
|
+
extend ActiveSupport::Concern
|
52
|
+
|
53
|
+
included do |base|
|
54
|
+
clear_validators! if respond_to?(:clear_validators!)
|
55
|
+
|
56
|
+
# Current scope for finding the most recent history
|
57
|
+
scope :current, -> { where(history_ended_at: nil).order(id: :desc) }
|
58
|
+
|
59
|
+
# Determine original class name
|
60
|
+
cattr_accessor :original_class_name
|
61
|
+
self.original_class_name = base.name.gsub(/History$/, '')
|
62
|
+
|
63
|
+
# Setup inheritance column for history classes
|
64
|
+
if self.original_class_name.constantize.respond_to?(:inheritance_column)
|
65
|
+
original_inheritance_column = self.original_class_name.constantize.inheritance_column
|
66
|
+
self.inheritance_column = original_inheritance_column
|
67
|
+
end
|
68
|
+
|
69
|
+
# Set up user association
|
70
|
+
unless self.original_class_name.constantize.ancestors.include?(Historiographer::Silent)
|
71
|
+
belongs_to :user, foreign_key: :history_user_id
|
72
|
+
end
|
73
|
+
|
74
|
+
# Ensure we can't destroy history records
|
75
|
+
before_destroy { |record| raise "Cannot destroy history records" }
|
76
|
+
|
77
|
+
# Handle type column for history classes
|
78
|
+
after_initialize do
|
79
|
+
# Set type to the history class if not already set
|
80
|
+
if self.type.nil? || !self.type.ends_with?('History')
|
81
|
+
self.type = self.class.name
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Setup class accessors for delegation
|
86
|
+
cattr_accessor :delegated_methods
|
87
|
+
self.delegated_methods = []
|
88
|
+
end
|
89
|
+
|
90
|
+
# Method delegation system
|
91
|
+
def method_missing(method, *args, &block)
|
92
|
+
# Try to find the original record to delegate to
|
93
|
+
foreign_key = self.class.determine_foreign_key
|
94
|
+
original_record = self.class.original_class_name.constantize.find_by(id: send(foreign_key))
|
95
|
+
|
96
|
+
if original_record && original_record.respond_to?(method)
|
97
|
+
# Cache the method for future calls
|
98
|
+
self.class.delegate_method(method)
|
99
|
+
# Call the method on the original record
|
100
|
+
original_record.send(method, *args, &block)
|
101
|
+
else
|
102
|
+
super
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def respond_to_missing?(method, include_private = false)
|
107
|
+
# Check if the original class responds to this method
|
108
|
+
foreign_key = self.class.determine_foreign_key
|
109
|
+
original_record = self.class.original_class_name.constantize.find_by(id: send(foreign_key))
|
110
|
+
original_record&.respond_to?(method, include_private) || super
|
111
|
+
end
|
112
|
+
|
113
|
+
class_methods do
|
114
|
+
# Method to delegate methods from original class
|
115
|
+
def delegate_method(method_name)
|
116
|
+
return if method_defined?(method_name) || delegated_methods.include?(method_name.to_sym)
|
117
|
+
|
118
|
+
delegated_methods << method_name.to_sym
|
119
|
+
|
120
|
+
define_method(method_name) do |*args, &block|
|
121
|
+
foreign_key = self.class.determine_foreign_key
|
122
|
+
original_record = self.class.original_class_name.constantize.find_by(id: send(foreign_key))
|
123
|
+
|
124
|
+
if original_record
|
125
|
+
original_record.send(method_name, *args, &block)
|
126
|
+
else
|
127
|
+
raise NoMethodError, "undefined method `#{method_name}' for #{self}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Determine the foreign key based on the original class
|
133
|
+
def determine_foreign_key
|
134
|
+
association_name = self.original_class_name.split("::").last.underscore
|
135
|
+
"#{association_name}_id"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Prevent destroying history records
|
140
|
+
def destroy
|
141
|
+
false
|
142
|
+
end
|
143
|
+
|
144
|
+
def destroy!
|
145
|
+
false
|
146
|
+
end
|
147
|
+
|
148
|
+
# Other existing scopes and methods...
|
149
|
+
end
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
153
|
+
### 2. Update Original Model STI Support in `Historiographer` Module
|
154
|
+
|
155
|
+
#### Changes Required:
|
156
|
+
|
157
|
+
- Ensure proper type column handling in original models
|
158
|
+
- Support proper mapping between original and history class hierarchy
|
159
|
+
- Handle custom inheritance columns
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
module Historiographer
|
163
|
+
extend ActiveSupport::Concern
|
164
|
+
|
165
|
+
included do |base|
|
166
|
+
# Existing code...
|
167
|
+
|
168
|
+
# Set default type for original models
|
169
|
+
if base.respond_to?(:inheritance_column) && base.column_names.include?(base.inheritance_column)
|
170
|
+
before_validation do
|
171
|
+
self[self.class.inheritance_column] ||= self.class.name
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Ensure history class creation supports STI
|
176
|
+
class_name = "#{base.name}History"
|
177
|
+
|
178
|
+
begin
|
179
|
+
history_class = class_name.constantize
|
180
|
+
rescue NameError
|
181
|
+
# Get the base table name without _histories suffix
|
182
|
+
base_table = base.table_name.singularize.sub(/_histories$/, '')
|
183
|
+
|
184
|
+
# Find the correct parent history class for STI
|
185
|
+
if base.superclass != ActiveRecord::Base && base.superclass.include?(Historiographer)
|
186
|
+
parent_history_class_name = "#{base.superclass.name}History"
|
187
|
+
begin
|
188
|
+
parent_history_class = parent_history_class_name.constantize
|
189
|
+
rescue NameError
|
190
|
+
parent_history_class = ActiveRecord::Base
|
191
|
+
end
|
192
|
+
else
|
193
|
+
parent_history_class = ActiveRecord::Base
|
194
|
+
end
|
195
|
+
|
196
|
+
# Create history class with proper inheritance
|
197
|
+
history_class_initializer = Class.new(parent_history_class) do
|
198
|
+
self.table_name = "#{base_table}_histories"
|
199
|
+
include Historiographer::History
|
200
|
+
|
201
|
+
# Set original class name for delegation
|
202
|
+
self.original_class_name = base.name
|
203
|
+
|
204
|
+
# Handle inheritance column
|
205
|
+
if base.respond_to?(:inheritance_column)
|
206
|
+
self.inheritance_column = base.inheritance_column
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Register the new class in the proper namespace
|
211
|
+
module_parts = class_name.split('::')
|
212
|
+
final_class_name = module_parts.pop
|
213
|
+
|
214
|
+
# Find or create module nesting
|
215
|
+
parent_module = Object
|
216
|
+
module_parts.each do |part|
|
217
|
+
parent_module = if parent_module.const_defined?(part)
|
218
|
+
parent_module.const_get(part)
|
219
|
+
else
|
220
|
+
parent_module.const_set(part, Module.new)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Define the history class
|
225
|
+
history_class = parent_module.const_set(final_class_name, history_class_initializer)
|
226
|
+
end
|
227
|
+
|
228
|
+
# Existing code...
|
229
|
+
end
|
230
|
+
|
231
|
+
# Add helper methods for STI
|
232
|
+
module ClassMethods
|
233
|
+
def history_class_for_type(type_value)
|
234
|
+
if type_value.present?
|
235
|
+
"#{type_value}History".constantize
|
236
|
+
else
|
237
|
+
"#{self.name}History".constantize
|
238
|
+
end
|
239
|
+
rescue NameError
|
240
|
+
history_class
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Instance methods related to history and STI
|
245
|
+
def create_history(snapshot_id: nil)
|
246
|
+
# Use the correct history class based on the current type
|
247
|
+
type_column = self.class.inheritance_column
|
248
|
+
current_type = self[type_column] || self.class.name
|
249
|
+
|
250
|
+
begin
|
251
|
+
specific_history_class = self.class.history_class_for_type(current_type)
|
252
|
+
rescue NameError
|
253
|
+
specific_history_class = self.class.history_class
|
254
|
+
end
|
255
|
+
|
256
|
+
# Create history record with the proper type
|
257
|
+
history_record = record_history(specific_history_class, snapshot_id: snapshot_id)
|
258
|
+
history_record
|
259
|
+
end
|
260
|
+
end
|
261
|
+
```
|
262
|
+
|
263
|
+
## Migration Testing Requirements
|
264
|
+
|
265
|
+
1. Create comprehensive test cases for STI behavior in original and history models
|
266
|
+
2. Test inheritance between original models (e.g., `PrivatePost < Post`)
|
267
|
+
3. Test inheritance between history models (e.g., `PrivatePostHistory < PostHistory`)
|
268
|
+
4. Test method delegation from history models to original models
|
269
|
+
5. Test custom inheritance columns
|
270
|
+
6. Test namespaced models
|
271
|
+
7. Verify proper handling of the `type` column in both original and history tables
|
272
|
+
|
273
|
+
## Backward Compatibility
|
274
|
+
|
275
|
+
To ensure backward compatibility:
|
276
|
+
|
277
|
+
1. Maintain existing history table structures
|
278
|
+
2. Ensure old history records continue to work with the new implementation
|
279
|
+
3. Support the same public API for accessing history records
|
280
|
+
4. Handle existing applications that may have customized history class behavior
|
281
|
+
|
282
|
+
By implementing STI separately within original and history models, we maintain Rails conventions while providing clean method delegation between related models.
|
@@ -0,0 +1,96 @@
|
|
1
|
+
## Context
|
2
|
+
|
3
|
+
You are assisting with a Rails gem called Historiographer. Your role is to make precise, surgical edits to the codebase based on specific tasks. The project has a complex architecture with interdependent components, so caution is required.
|
4
|
+
|
5
|
+
## Task:
|
6
|
+
|
7
|
+
We are going to PROPERLY implement Single Table Inheritance (STI) for Historiographer, in line with Rails best practices.
|
8
|
+
|
9
|
+
There is some existing code in here that implements STI, but it is not done correctly. We need to fix that.
|
10
|
+
|
11
|
+
## Requirements:
|
12
|
+
|
13
|
+
1. User can define a `type` for their class, and that will be used to identify the STI class
|
14
|
+
2. In keeping with STI conventions, the `type` should be a string, and the default value should be the class name
|
15
|
+
3. When a user creates a new instance of a class, the `type` should be set to the class name, and the class should automatically inherit the STI class
|
16
|
+
|
17
|
+
In historiographer, we use a `histories` table for each model, for example:
|
18
|
+
|
19
|
+
datasources => datasource_histories
|
20
|
+
|
21
|
+
With STI, it is okay for us to have:
|
22
|
+
|
23
|
+
class Datasource < ActiveRecord::Base
|
24
|
+
def refresh # implemented in sub-classes
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class S3Datasource < Datasource
|
29
|
+
def refresh
|
30
|
+
s3.refresh
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class DatasourceHistory < Datasource
|
35
|
+
end
|
36
|
+
|
37
|
+
class S3DatasourceHistory < DatasourceHistory
|
38
|
+
end
|
39
|
+
|
40
|
+
4. But the STI class should automatically inherit the STI class, allowing it to use methods defined on the STI class, meaning that S3DatasourceHistory should have access to the `refresh` method that uses s3
|
41
|
+
|
42
|
+
5. When we find an instance of DatasourceHistory, it should automatically give us the S3DatasourceHistory class if the `type` is "S3Datasource"
|
43
|
+
|
44
|
+
6. The History classes currently have a VERY tricky and complicated way of doing STI that allows them to both act as proper history classes, and "proxy all requests" to the original class. This causes complicated and subtle bugs, and we need to fix that. I would assume that we should do this by inheriting from the original class, which will handle regular inheritance... but then we maybe need to include Historiographer::History to gain access to the history functionality.
|
45
|
+
|
46
|
+
7. Implement tests which verify that the STI is working correctly, and that History objects can properly call all methods on the original class.
|
47
|
+
|
48
|
+
## Rules
|
49
|
+
|
50
|
+
### Do No Harm
|
51
|
+
|
52
|
+
- Do not remove any code that seems to be irrelevant to your task. You do not have full context of the application, so you should err on the side of NOT removing code, unless the code is clearly duplication.
|
53
|
+
- Preserve existing formatting, naming conventions, and code style whenever possible.
|
54
|
+
- Keep changes minimal and focused on the specific task at hand.
|
55
|
+
|
56
|
+
### Before Starting
|
57
|
+
|
58
|
+
- Look for any files you might need to understand the context better
|
59
|
+
- If you have any questions, DO NOT WRITE CODE. Ask the question. I will be happy to answer all your questions to your satisfaction before you start.
|
60
|
+
- Measure twice, cut once!
|
61
|
+
- Understand the full impact of your changes before implementing them.
|
62
|
+
|
63
|
+
### Working Process
|
64
|
+
|
65
|
+
1. **Analyze First**: Carefully review the code before suggesting any changes.
|
66
|
+
2. **Ask Questions**: If anything is unclear, ask before proceeding.
|
67
|
+
3. **Plan Your Approach**: Outline your intended changes before executing them.
|
68
|
+
4. **Make Minimal Changes**: Focus only on what's needed for the task.
|
69
|
+
5. **Explain Your Changes**: Document what you've done and why.
|
70
|
+
|
71
|
+
## Technology-Specific Guidelines
|
72
|
+
|
73
|
+
### Rails
|
74
|
+
|
75
|
+
- Be aware of model associations and their dependencies.
|
76
|
+
- Don't alter database migrations unless specifically asked.
|
77
|
+
- Pay attention to Rails conventions and patterns in the existing code.
|
78
|
+
- Be cautious when modifying controllers that might affect multiple views.
|
79
|
+
|
80
|
+
## Common Pitfalls to Avoid
|
81
|
+
|
82
|
+
- Adding unnecessary abstractions or "improvements" beyond the scope of the task
|
83
|
+
- Rewriting functional code in your preferred style when it's not needed
|
84
|
+
- Making major architectural changes when only small fixes are required
|
85
|
+
- Assuming you understand the full context of the application
|
86
|
+
- Using libraries or approaches not already in use in the project
|
87
|
+
|
88
|
+
## Communication Guidelines
|
89
|
+
|
90
|
+
- Be specific about what you're changing and why
|
91
|
+
- If you're uncertain about something, ask first
|
92
|
+
- Identify potential risks or side effects of your changes
|
93
|
+
- If you spot issues unrelated to your task, note them separately without fixing them
|
94
|
+
- Provide clear explanations of your thought process
|
95
|
+
|
96
|
+
Remember: Your primary goal is to complete the specific task assigned with minimal disruption to the existing codebase. Quality and precision are more important than clever or extensive changes.
|
@@ -317,13 +317,7 @@ module Historiographer
|
|
317
317
|
|
318
318
|
def sti_base_class
|
319
319
|
return @sti_base_class if @sti_base_class
|
320
|
-
|
321
|
-
base_name = name.gsub(/History$/, '')
|
322
|
-
base_class = base_name.constantize
|
323
|
-
while base_class.superclass != ActiveRecord::Base
|
324
|
-
base_class = base_class.superclass
|
325
|
-
end
|
326
|
-
@sti_base_class = base_class
|
320
|
+
@sti_base_class = original_class.base_class
|
327
321
|
end
|
328
322
|
end
|
329
323
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
development:
|
2
|
+
adapter: postgresql
|
3
|
+
encoding: unicode
|
4
|
+
database: historiographer_development
|
5
|
+
pool: 5
|
6
|
+
|
7
|
+
test:
|
8
|
+
adapter: postgresql
|
9
|
+
encoding: unicode
|
10
|
+
database: historiographer_test
|
11
|
+
pool: 5
|
12
|
+
|
13
|
+
# mysql_default: &mysql_default
|
14
|
+
# adapter: mysql2
|
15
|
+
# encoding: utf8
|
16
|
+
# username: root
|
17
|
+
# password:
|
18
|
+
# host: 127.0.0.1
|
19
|
+
# port: 3306
|
20
|
+
|
21
|
+
# development:
|
22
|
+
# <<: *mysql_default
|
23
|
+
# database: historiographer_development
|
24
|
+
|
25
|
+
# test:
|
26
|
+
# <<: *mysql_default
|
27
|
+
# database: historiographer_test
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreatePosts < ActiveRecord::Migration[5.1]
|
2
|
+
def change
|
3
|
+
create_table :posts do |t|
|
4
|
+
t.string :title, null: false
|
5
|
+
t.text :body, null: false
|
6
|
+
t.integer :author_id, null: false
|
7
|
+
t.boolean :enabled, default: false
|
8
|
+
t.datetime :live_at
|
9
|
+
t.datetime :deleted_at
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :posts, :author_id
|
15
|
+
add_index :posts, :enabled
|
16
|
+
add_index :posts, :live_at
|
17
|
+
add_index :posts, :deleted_at
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateSafePosts < ActiveRecord::Migration[5.1]
|
2
|
+
def change
|
3
|
+
create_table :safe_posts do |t|
|
4
|
+
t.string :title, null: false
|
5
|
+
t.text :body, null: false
|
6
|
+
t.integer :author_id, null: false
|
7
|
+
t.boolean :enabled, default: false
|
8
|
+
t.datetime :live_at
|
9
|
+
t.datetime :deleted_at
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
add_index :safe_posts, :author_id
|
15
|
+
add_index :safe_posts, :enabled
|
16
|
+
add_index :safe_posts, :live_at
|
17
|
+
add_index :safe_posts, :deleted_at
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "historiographer/postgres_migration"
|
2
|
+
class CreateThingWithCompoundIndexHistory < ActiveRecord::Migration[5.2]
|
3
|
+
def change
|
4
|
+
create_table :thing_with_compound_index_histories do |t|
|
5
|
+
t.histories index_names: {
|
6
|
+
[:key, :value] => "idx_history_k_v",
|
7
|
+
:thing_with_compound_index_id => "idx_k_v_histories"
|
8
|
+
}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateSilentPosts < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :silent_posts do |t|
|
6
|
+
t.string :title, null: false
|
7
|
+
t.text :body, null: false
|
8
|
+
t.integer :author_id, null: false
|
9
|
+
t.boolean :enabled, default: false
|
10
|
+
t.datetime :live_at
|
11
|
+
t.datetime :deleted_at
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :silent_posts, :author_id
|
17
|
+
add_index :silent_posts, :enabled
|
18
|
+
add_index :silent_posts, :live_at
|
19
|
+
add_index :silent_posts, :deleted_at
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "historiographer/postgres_migration"
|
2
|
+
require "historiographer/mysql_migration"
|
3
|
+
|
4
|
+
class CreateMlModels < ActiveRecord::Migration[7.0]
|
5
|
+
def change
|
6
|
+
create_table :ml_models do |t|
|
7
|
+
t.string :name
|
8
|
+
t.string :model_type
|
9
|
+
t.jsonb :parameters
|
10
|
+
t.timestamps
|
11
|
+
|
12
|
+
t.index :model_type
|
13
|
+
end
|
14
|
+
|
15
|
+
create_table :ml_model_histories do |t|
|
16
|
+
t.histories
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "historiographer/postgres_migration"
|
2
|
+
require "historiographer/mysql_migration"
|
3
|
+
|
4
|
+
class CreateEasyMlColumns < ActiveRecord::Migration[7.1]
|
5
|
+
def change
|
6
|
+
create_table :easy_ml_columns do |t|
|
7
|
+
t.string :name, null: false
|
8
|
+
t.string :data_type, null: false
|
9
|
+
t.string :column_type
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
create_table :easy_ml_column_histories do |t|
|
14
|
+
t.histories(foreign_key: :column_id)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|