activerecord-temporal 0.3.0 → 0.4.0
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/CHANGELOG.md +5 -0
- data/README.md +15 -6
- data/lib/activerecord/temporal/version.rb +1 -1
- data/lib/activerecord/temporal.rb +14 -6
- metadata +1 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 230f188aed78df98d3121bf21436905bb21cb314b6626c7f741eaf40f250e43c
|
|
4
|
+
data.tar.gz: 7c8822ad52d0d529222c0a619f2fdfae3436485ce6c479b61095e3d0bdc5b9e5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4db33aa953f22cba846b1742b263f4051fea0b58cdbe92332a6d3b54f3fab4b64ffdb3edb2c3bd8de4dd4a84724a312d7cff589619495f54594c123ed152948f
|
|
7
|
+
data.tar.gz: 0636ff55084af4222059a8d5235df0eb538bee8132fb5a80c9f7bc58579c6b05f790d5150b5f8a1e3d8f39fecb80404acf679587b4ed1056169fa6cb9fa7f852
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.4.0] - 2025-12-02
|
|
4
|
+
|
|
5
|
+
- Nest `HistoryModelNamespace` directly in `ActiveRecord::Temporal` as per the README
|
|
6
|
+
- Fixed issue where including `ActiveRecord::Temporal` would not extend the base module properly
|
|
7
|
+
|
|
3
8
|
## [0.3.0] - 2025-11-20
|
|
4
9
|
|
|
5
10
|
- Application versioning: Raise `ClosedRevisionError` when trying to revise or inactive closed versions.
|
data/README.md
CHANGED
|
@@ -10,7 +10,7 @@ As applications mature, changing business requirements become increasingly compl
|
|
|
10
10
|
|
|
11
11
|
- Know the price of a product at the time it was added to a cart
|
|
12
12
|
- Allow users to see content as it was before their subscription ended
|
|
13
|
-
- Track the lifetime of long-lived, slowly
|
|
13
|
+
- Track the lifetime of long-lived, slowly changing entities like projects or customers
|
|
14
14
|
- Generate reports based on the data as it was known at some time in the past
|
|
15
15
|
|
|
16
16
|
Many Rails applications use a patchwork of approaches:
|
|
@@ -20,7 +20,7 @@ Many Rails applications use a patchwork of approaches:
|
|
|
20
20
|
- **Event systems** that are used to fill gaps in the data model and gradually take on responsibilities that are implementation details with no business relevance.
|
|
21
21
|
- **Ad-hoc snapshot columns** that result in important business entities having their historical data duplicated across many different and incohesive tables.
|
|
22
22
|
|
|
23
|
-
Temporal
|
|
23
|
+
Temporal tables address these problems by providing a simple and coherent data model to reach for whenever historical data is needed.
|
|
24
24
|
|
|
25
25
|
This can be a versioning strategy that operates automatically at the database level or one where versioning is used up front as the default method for all CRUD operations on a table.
|
|
26
26
|
|
|
@@ -29,6 +29,10 @@ This can be a versioning strategy that operates automatically at the database le
|
|
|
29
29
|
- Active Record >= 8
|
|
30
30
|
- PostgreSQL >= 13
|
|
31
31
|
|
|
32
|
+
## Stability
|
|
33
|
+
|
|
34
|
+
⚠️ Currently a beta release. Breaking changes will bump the minor version until the 1.x.x release.
|
|
35
|
+
|
|
32
36
|
## Quick Start
|
|
33
37
|
|
|
34
38
|
```ruby
|
|
@@ -36,8 +40,13 @@ This can be a versioning strategy that operates automatically at the database le
|
|
|
36
40
|
|
|
37
41
|
gem "activerecord-temporal"
|
|
38
42
|
```
|
|
43
|
+
### Versioning Strategies
|
|
44
|
+
|
|
45
|
+
This gem supports two versioning strategies:
|
|
46
|
+
1. **System versioning**, where database triggers automatically maintain a separate history table that records transaction time.
|
|
47
|
+
2. **Application versioning**, where versioning is managed by the application using a single table whose time dimension can represent validity or any other temporal business concept.
|
|
39
48
|
|
|
40
|
-
###
|
|
49
|
+
### Creating a System Versioned Table
|
|
41
50
|
|
|
42
51
|
Make sure you're using the `:sql` schema dumper.
|
|
43
52
|
|
|
@@ -121,7 +130,7 @@ Employee.history.as_of(Time.parse("2000-01-10"))
|
|
|
121
130
|
- [System Versioning](#system-versioning)
|
|
122
131
|
- [History Model Namespace](#history-model-namespace)
|
|
123
132
|
|
|
124
|
-
###
|
|
133
|
+
### Creating an Application Versioned Table
|
|
125
134
|
|
|
126
135
|
Create an `employees` table with a `version` column in the primary key and a `tstzrange` column to be the time dimension.
|
|
127
136
|
|
|
@@ -192,7 +201,7 @@ Employee.as_of(Time.parse("2000-02-15"))
|
|
|
192
201
|
- [Application Versioning](#application-versioning)
|
|
193
202
|
- [Foreign Key Constraints](#foreign-key-constraints)
|
|
194
203
|
|
|
195
|
-
###
|
|
204
|
+
### Making Time-travel Queries
|
|
196
205
|
|
|
197
206
|
This interface works the same with system versioning and application. But this example assumes at least the `Product` and `Order` models are system versioned:
|
|
198
207
|
|
|
@@ -510,7 +519,7 @@ class Product < ApplicationRecord
|
|
|
510
519
|
end
|
|
511
520
|
```
|
|
512
521
|
|
|
513
|
-
The only strict requirements for
|
|
522
|
+
The only strict requirements for an application versioned table are:
|
|
514
523
|
1. It must have a `tstzrange` column (name doesn't matter)
|
|
515
524
|
2. It must have a numeric `version` column with a default value
|
|
516
525
|
|
|
@@ -29,16 +29,24 @@ require_relative "temporal/system_versioning"
|
|
|
29
29
|
require_relative "temporal/version"
|
|
30
30
|
|
|
31
31
|
module ActiveRecord::Temporal
|
|
32
|
-
def
|
|
33
|
-
|
|
32
|
+
def self.included(base)
|
|
33
|
+
base.extend ClassMethods
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
module ClassMethods
|
|
37
|
+
def system_versioning
|
|
38
|
+
include SystemVersioning
|
|
39
|
+
end
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
def application_versioning(**options)
|
|
42
|
+
include Querying
|
|
43
|
+
include ApplicationVersioning
|
|
44
|
+
|
|
45
|
+
self.time_dimensions = options[:dimensions] if options[:dimensions]
|
|
46
|
+
end
|
|
41
47
|
end
|
|
48
|
+
|
|
49
|
+
HistoryModelNamespace = SystemVersioning::HistoryModelNamespace
|
|
42
50
|
end
|
|
43
51
|
|
|
44
52
|
ActiveSupport.on_load(:active_record) do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-temporal
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Martin-Alexander
|
|
@@ -29,26 +29,6 @@ dependencies:
|
|
|
29
29
|
- - "<"
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
31
|
version: '9.0'
|
|
32
|
-
- !ruby/object:Gem::Dependency
|
|
33
|
-
name: activesupport
|
|
34
|
-
requirement: !ruby/object:Gem::Requirement
|
|
35
|
-
requirements:
|
|
36
|
-
- - ">="
|
|
37
|
-
- !ruby/object:Gem::Version
|
|
38
|
-
version: '8'
|
|
39
|
-
- - "<"
|
|
40
|
-
- !ruby/object:Gem::Version
|
|
41
|
-
version: '9.0'
|
|
42
|
-
type: :runtime
|
|
43
|
-
prerelease: false
|
|
44
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
-
requirements:
|
|
46
|
-
- - ">="
|
|
47
|
-
- !ruby/object:Gem::Version
|
|
48
|
-
version: '8'
|
|
49
|
-
- - "<"
|
|
50
|
-
- !ruby/object:Gem::Version
|
|
51
|
-
version: '9.0'
|
|
52
32
|
- !ruby/object:Gem::Dependency
|
|
53
33
|
name: pg
|
|
54
34
|
requirement: !ruby/object:Gem::Requirement
|