hoardable 0.1.2 → 0.2.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/Gemfile +1 -0
- data/README.md +69 -9
- data/lib/generators/hoardable/migration_generator.rb +2 -1
- data/lib/hoardable/error.rb +1 -1
- data/lib/hoardable/hoardable.rb +14 -3
- data/lib/hoardable/model.rb +27 -2
- data/lib/hoardable/source_model.rb +34 -5
- data/lib/hoardable/tableoid.rb +21 -1
- data/lib/hoardable/version.rb +1 -1
- data/lib/hoardable/version_model.rb +29 -1
- data/sig/hoardable.rbs +83 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c960d95a373942d9183464cc50b7c4213c25c7563fa9d920c81d2c325ea71705
|
4
|
+
data.tar.gz: e7e0f289e60acd720538edc15584209ed3d30e08b21758d06884a5486f198ee0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a83966223151922d24bb009ac50465723388ba91825e27cf933bb5e00370c270a0518ec828358f1109a040e2a9202cee7b37d7ea98e0387b30dc07a74f7eb851
|
7
|
+
data.tar.gz: 6bc246f6664b61c5000ffa71b24c8ddd30c409eda87e790b0ea1bd9d47f46c4e85e0b5eb89736939a75018e272cdd5ac2ce1217c7c7e9272ddc4f96cc8cc33f4
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
Hoardable is an ActiveRecord extension for Ruby 2.6+, Rails 6.1+, and PostgreSQL that allows for
|
4
4
|
versioning and soft-deletion of records through the use of _uni-temporal inherited tables_.
|
5
5
|
|
6
|
-
#### huh?
|
7
|
-
|
8
6
|
[Temporal tables](https://en.wikipedia.org/wiki/Temporal_database) are a database design pattern
|
9
7
|
where each row of a table contains data along with one or more time ranges. In the case of this gem,
|
10
8
|
each database row has a time range that represents the row’s valid time range - hence
|
@@ -18,8 +16,10 @@ change is reflected on its descendants.
|
|
18
16
|
With these concepts combined, `hoardable` offers a simple and effective model versioning system for
|
19
17
|
Rails. Versions of records are stored in separate, inherited tables along with their valid time
|
20
18
|
ranges and contextual data. Compared to other Rails-oriented versioning systems, this gem strives to
|
21
|
-
be more explicit and obvious on the lower RDBS level while still familiar and convenient
|
22
|
-
on Rails.
|
19
|
+
be more explicit and obvious on the lower RDBS level while still familiar and convenient to use
|
20
|
+
within Ruby on Rails.
|
21
|
+
|
22
|
+
[👉 Documentation](https://www.rubydoc.info/gems/hoardable)
|
23
23
|
|
24
24
|
## Installation
|
25
25
|
|
@@ -117,6 +117,10 @@ post.at(1.day.ago) # => #<PostVersion:0x000000010d44fa30>
|
|
117
117
|
PostVersion.at(1.day.ago).find_by(post_id: post.id) # => #<PostVersion:0x000000010d44fa30>
|
118
118
|
```
|
119
119
|
|
120
|
+
_Note:_ A `Version` is not created upon initial parent model creation. If you would like to
|
121
|
+
accurately capture the valid temporal frame of the first version, make sure your model’s table has a
|
122
|
+
`created_at` timestamp field.
|
123
|
+
|
120
124
|
By default, `hoardable` will keep copies of records you have destroyed. You can query for them as
|
121
125
|
well:
|
122
126
|
|
@@ -127,7 +131,7 @@ PostVersion.trashed
|
|
127
131
|
_Note:_ Creating an inherited table does not copy over the indexes from the parent table. If you
|
128
132
|
need to query versions often, you should add appropriate indexes to the `_versions` tables.
|
129
133
|
|
130
|
-
### Tracking
|
134
|
+
### Tracking Contextual Data
|
131
135
|
|
132
136
|
You’ll often want to track contextual data about the creation of a version. There are 3 optional
|
133
137
|
symbol keys that are provided for tracking contextual information:
|
@@ -220,19 +224,22 @@ end
|
|
220
224
|
|
221
225
|
### Configuration
|
222
226
|
|
223
|
-
There are
|
227
|
+
There are three configurable options currently:
|
224
228
|
|
225
229
|
```ruby
|
226
230
|
Hoardable.enabled # => default true
|
231
|
+
Hoardable.version_updates # => default true
|
227
232
|
Hoardable.save_trash # => default true
|
228
233
|
```
|
229
234
|
|
230
|
-
`Hoardable.enabled` controls whether versions will be
|
235
|
+
`Hoardable.enabled` controls whether versions will be ever be created.
|
236
|
+
|
237
|
+
`Hoardable.version_updates` controls whether versions get created on record updates.
|
231
238
|
|
232
239
|
`Hoardable.save_trash` controls whether to create versions upon record deletion. When this is set to
|
233
240
|
`false`, all versions of a record will be deleted when the record is destroyed.
|
234
241
|
|
235
|
-
If you would like to temporarily set a config setting, you can use `Hoardable.with
|
242
|
+
If you would like to temporarily set a config setting, you can use `Hoardable.with`:
|
236
243
|
|
237
244
|
```ruby
|
238
245
|
Hoardable.with(enabled: false) do
|
@@ -240,6 +247,18 @@ Hoardable.with(enabled: false) do
|
|
240
247
|
end
|
241
248
|
```
|
242
249
|
|
250
|
+
You can also configure these variables per `ActiveRecord` class as well using `hoardable_options`:
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
class Comment < ActiveRecord::Base
|
254
|
+
include Hoardable::Model
|
255
|
+
hoardable_options version_updates: false
|
256
|
+
end
|
257
|
+
```
|
258
|
+
|
259
|
+
If either the model-level option or global option for a configuration variable is set to `false`,
|
260
|
+
that behavior will be disabled.
|
261
|
+
|
243
262
|
### Relationships
|
244
263
|
|
245
264
|
As in life, sometimes relationships can be hard. `hoardable` is still working out best practices and
|
@@ -269,15 +288,56 @@ class Post < ActiveRecord::Base
|
|
269
288
|
Comment
|
270
289
|
.version_class
|
271
290
|
.trashed
|
291
|
+
.where(post_id: id)
|
272
292
|
.with_hoardable_event_uuid(hoardable_event_uuid)
|
273
293
|
.find_each(&:untrash!)
|
274
294
|
end
|
275
295
|
end
|
276
296
|
```
|
277
297
|
|
298
|
+
## Gem Comparison
|
299
|
+
|
300
|
+
### [`paper_trail`](https://github.com/paper-trail-gem/paper_trail)
|
301
|
+
|
302
|
+
`paper_trail` is maybe the most popular and fully featured gem in this space. It works for other
|
303
|
+
database types than PostgeSQL and (by default) stores all versions of all versioned models in a
|
304
|
+
single `versions` table. It stores changes in a `text`, `json`, or `jsonb` column. In order to
|
305
|
+
efficiently query the `versions` table, a `jsonb` column should be used, which takes up a lot of
|
306
|
+
space to index. Unless you customize your configuration, all `versions` for all models types are
|
307
|
+
in the same table which is inefficient if you are only interested in querying versions of a single
|
308
|
+
model. By contrast, `hoardable` stores versions in smaller, isolated and inherited tables with the
|
309
|
+
same database columns as their parents, which are more efficient for querying as well as auditing
|
310
|
+
for truncating and dropping. The concept of a `temporal` time-frame does not exist for a single
|
311
|
+
version since there is only a `created_at` timestamp.
|
312
|
+
|
313
|
+
### [`audited`](https://github.com/collectiveidea/audited)
|
314
|
+
|
315
|
+
`audited` works in a similar manner as `paper_trail`. It stores all versions for all model types in
|
316
|
+
a single table, you must opt into using `jsonb` as the column type to store "changes", in case you
|
317
|
+
want to query them, and there is no concept of a `temporal` time-frame for a single version. It
|
318
|
+
makes opinionated decisions about contextual data requirements and stores them as top level data
|
319
|
+
types on the `audited` table.
|
320
|
+
|
321
|
+
### [`discard`](https://github.com/jhawthorn/discard)
|
322
|
+
|
323
|
+
`discard` only covers soft-deletion. The act of "soft deleting" a record is only captured through
|
324
|
+
the time-stamping of a `discarded_at` column on the records table; there is no other capturing of
|
325
|
+
the event that caused the soft deletion unless you implement it yourself. Once the "discarded"
|
326
|
+
record is restored, the previous "discarded" awareness is lost. Since "discarded" records exist in
|
327
|
+
the same table as "undiscarded" records, you must explicitly omit the discarded records from queries
|
328
|
+
across your app to keep them from leaking in.
|
329
|
+
|
330
|
+
### [`paranoia`](https://github.com/rubysherpas/paranoia)
|
331
|
+
|
332
|
+
`paranoia` also only covers soft-deletion. In their README, they recommend using `discard` instead
|
333
|
+
of `paranoia` because of the fact they override ActiveRecord’s `delete` and `destroy` methods.
|
334
|
+
`hoardable` employs callbacks to create trashed versions instead of overriding methods. Otherwise,
|
335
|
+
`paranoia` works similarly to `discard` in that it keeps deleted records in the same table and tags
|
336
|
+
them with a `deleted_at` timestamp. No other information about the soft-deletion event is stored.
|
337
|
+
|
278
338
|
## Contributing
|
279
339
|
|
280
|
-
This gem
|
340
|
+
This gem still quite new and very open to feedback.
|
281
341
|
|
282
342
|
Bug reports and pull requests are welcome on GitHub at https://github.com/waymondo/hoardable.
|
283
343
|
|
@@ -4,7 +4,8 @@ require 'rails/generators'
|
|
4
4
|
require 'rails/generators/active_record/migration/migration_generator'
|
5
5
|
|
6
6
|
module Hoardable
|
7
|
-
# Generates a migration
|
7
|
+
# Generates a migration to create an inherited uni-temporal table of a model including
|
8
|
+
# {Hoardable::Model}, for the storage of +versions+.
|
8
9
|
class MigrationGenerator < ActiveRecord::Generators::Base
|
9
10
|
source_root File.expand_path('templates', __dir__)
|
10
11
|
include Rails::Generators::Migration
|
data/lib/hoardable/error.rb
CHANGED
data/lib/hoardable/hoardable.rb
CHANGED
@@ -1,13 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# An ActiveRecord extension for keeping versions of records in temporal inherited tables
|
3
|
+
# An +ActiveRecord+ extension for keeping versions of records in uni-temporal inherited tables.
|
4
4
|
module Hoardable
|
5
|
+
# Symbols for use with setting contextual data, when creating versions. See
|
6
|
+
# {file:README.md#tracking-contextual-data README} for more.
|
5
7
|
DATA_KEYS = %i[meta whodunit note event_uuid].freeze
|
6
|
-
|
8
|
+
# Symbols for use with setting {Hoardable} configuration. See {file:README.md#configuration
|
9
|
+
# README} for more.
|
10
|
+
CONFIG_KEYS = %i[enabled version_updates save_trash].freeze
|
7
11
|
|
12
|
+
# @!visibility private
|
8
13
|
VERSION_CLASS_SUFFIX = 'Version'
|
14
|
+
|
15
|
+
# @!visibility private
|
9
16
|
VERSION_TABLE_SUFFIX = "_#{VERSION_CLASS_SUFFIX.tableize}"
|
10
|
-
|
17
|
+
|
18
|
+
# @!visibility private
|
11
19
|
DURING_QUERY = '_during @> ?::timestamp'
|
12
20
|
|
13
21
|
@context = {}
|
@@ -36,6 +44,9 @@ module Hoardable
|
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
47
|
+
# This is a general use method for setting {DATA_KEYS} or {CONFIG_KEYS} around a scoped block.
|
48
|
+
#
|
49
|
+
# @param hash [Hash] Options and contextual data to set within a block
|
39
50
|
def with(hash)
|
40
51
|
current_config = @config
|
41
52
|
current_context = @context
|
data/lib/hoardable/model.rb
CHANGED
@@ -1,11 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Hoardable
|
4
|
-
# This concern
|
5
|
-
# the
|
4
|
+
# This concern is the main entrypoint for using {Hoardable}. When included into an +ActiveRecord+
|
5
|
+
# class, it dynamically generates the +Version+ variant of that class (with {VersionModel}) and
|
6
|
+
# includes the {Hoardable} API methods and relationships on the source model class (through
|
7
|
+
# {SourceModel}).
|
6
8
|
module Model
|
7
9
|
extend ActiveSupport::Concern
|
8
10
|
|
11
|
+
class_methods do
|
12
|
+
# @!visibility private
|
13
|
+
attr_reader :_hoardable_options
|
14
|
+
|
15
|
+
# If called with a hash, this will set the model-level +Hoardable+ configuration variables. If
|
16
|
+
# called without an argument it will return the computed +Hoardable+ configuration considering
|
17
|
+
# both model-level and global values.
|
18
|
+
#
|
19
|
+
# @param hash [Hash] The +Hoardable+ configuration for the model. Keys must be present in
|
20
|
+
# {CONFIG_KEYS}
|
21
|
+
# @return [Hash]
|
22
|
+
def hoardable_options(hash = nil)
|
23
|
+
if hash
|
24
|
+
@_hoardable_options = hash.slice(*Hoardable::CONFIG_KEYS)
|
25
|
+
else
|
26
|
+
@_hoardable_options ||= {}
|
27
|
+
Hoardable::CONFIG_KEYS.to_h do |key|
|
28
|
+
[key, Hoardable.send(key) != false && @_hoardable_options[key] != false]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
9
34
|
included do
|
10
35
|
define_model_callbacks :versioned
|
11
36
|
define_model_callbacks :reverted, only: :after
|
@@ -1,11 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Hoardable
|
4
|
-
# This concern contains the relationships, callbacks, and API methods for
|
4
|
+
# This concern contains the {Hoardable} relationships, callbacks, and API methods for an
|
5
|
+
# +ActiveRecord+. It is included by {Hoardable::Model} after the dynamic generation of the
|
6
|
+
# +Version+ class variant.
|
5
7
|
module SourceModel
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
|
8
10
|
class_methods do
|
11
|
+
# The dynamically generated +Version+ class for this model.
|
9
12
|
def version_class
|
10
13
|
"#{name}#{VERSION_CLASS_SUFFIX}".constantize
|
11
14
|
end
|
@@ -14,15 +17,22 @@ module Hoardable
|
|
14
17
|
included do
|
15
18
|
include Tableoid
|
16
19
|
|
17
|
-
around_update :insert_hoardable_version_on_update, if:
|
18
|
-
around_destroy :insert_hoardable_version_on_destroy, if: [
|
19
|
-
before_destroy :delete_hoardable_versions, if: :hoardable_callbacks_enabled, unless:
|
20
|
+
around_update :insert_hoardable_version_on_update, if: %i[hoardable_callbacks_enabled hoardable_version_updates]
|
21
|
+
around_destroy :insert_hoardable_version_on_destroy, if: %i[hoardable_callbacks_enabled hoardable_save_trash]
|
22
|
+
before_destroy :delete_hoardable_versions, if: :hoardable_callbacks_enabled, unless: :hoardable_save_trash
|
20
23
|
after_commit :unset_hoardable_version_and_event_uuid
|
21
24
|
|
25
|
+
# This will contain the +Version+ class instance for use within +versioned+, +reverted+, and
|
26
|
+
# +untrashed+ callbacks.
|
22
27
|
attr_reader :hoardable_version
|
23
28
|
|
29
|
+
# @!attribute [r] hoardable_event_uuid
|
30
|
+
# @return [String] A postgres UUID that represents the +version+’s +ActiveRecord+ database transaction
|
31
|
+
# @!attribute [r] hoardable_operation
|
32
|
+
# @return [String] The database operation that created the +version+ - either +update+ or +delete+.
|
24
33
|
delegate :hoardable_event_uuid, :hoardable_operation, to: :hoardable_version, allow_nil: true
|
25
34
|
|
35
|
+
# Returns all +versions+ in ascending order of their temporal timeframes.
|
26
36
|
has_many(
|
27
37
|
:versions, -> { order(:_during) },
|
28
38
|
dependent: nil,
|
@@ -31,16 +41,27 @@ module Hoardable
|
|
31
41
|
)
|
32
42
|
end
|
33
43
|
|
44
|
+
# Returns a boolean of whether the record is actually a trashed +version+.
|
45
|
+
#
|
46
|
+
# @return [Boolean]
|
34
47
|
def trashed?
|
35
48
|
versions.trashed.limit(1).order(_during: :desc).first&.send(:hoardable_source_attributes) == attributes
|
36
49
|
end
|
37
50
|
|
51
|
+
# Returns the +version+ at the supplied +datetime+ or +time+. It will return +self+ if there is
|
52
|
+
# none. This will raise an error if you try to find a version in the future.
|
53
|
+
#
|
54
|
+
# @param datetime [DateTime, Time]
|
38
55
|
def at(datetime)
|
39
56
|
raise(Error, 'Future state cannot be known') if datetime.future?
|
40
57
|
|
41
58
|
versions.find_by(DURING_QUERY, datetime) || self
|
42
59
|
end
|
43
60
|
|
61
|
+
# If a version is found at the supplied datetime, it will +revert!+ to it and return it. This
|
62
|
+
# will raise an error if you try to revert to a version in the future.
|
63
|
+
#
|
64
|
+
# @param datetime [DateTime, Time]
|
44
65
|
def revert_to!(datetime)
|
45
66
|
return unless (version = at(datetime))
|
46
67
|
|
@@ -50,7 +71,15 @@ module Hoardable
|
|
50
71
|
private
|
51
72
|
|
52
73
|
def hoardable_callbacks_enabled
|
53
|
-
|
74
|
+
self.class.hoardable_options[:enabled] && !self.class.name.end_with?(VERSION_CLASS_SUFFIX)
|
75
|
+
end
|
76
|
+
|
77
|
+
def hoardable_save_trash
|
78
|
+
self.class.hoardable_options[:save_trash]
|
79
|
+
end
|
80
|
+
|
81
|
+
def hoardable_version_updates
|
82
|
+
self.class.hoardable_options[:version_updates]
|
54
83
|
end
|
55
84
|
|
56
85
|
def insert_hoardable_version_on_update(&block)
|
data/lib/hoardable/tableoid.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Hoardable
|
4
|
-
# This concern provides support for PostgreSQL
|
4
|
+
# This concern provides support for PostgreSQL’s tableoid system column to {SourceModel}.
|
5
5
|
module Tableoid
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
+
# @!visibility private
|
8
9
|
TABLEOID_AREL_CONDITIONS = lambda do |arel_table, condition|
|
9
10
|
arel_table[:tableoid].send(
|
10
11
|
condition,
|
@@ -13,13 +14,32 @@ module Hoardable
|
|
13
14
|
end.freeze
|
14
15
|
|
15
16
|
included do
|
17
|
+
# @!visibility private
|
16
18
|
attr_writer :tableoid
|
17
19
|
|
20
|
+
# By default, {Hoardable} only returns instances of the parent table, and not the +versions+
|
21
|
+
# in the inherited table.
|
18
22
|
default_scope { where(TABLEOID_AREL_CONDITIONS.call(arel_table, :eq)) }
|
23
|
+
|
24
|
+
# @!scope class
|
25
|
+
# @!method include_versions
|
26
|
+
# @return [ActiveRecord<Object>]
|
27
|
+
#
|
28
|
+
# Returns +versions+ along with instances of the source models, all cast as instances of the
|
29
|
+
# source model’s class.
|
19
30
|
scope :include_versions, -> { unscope(where: [:tableoid]) }
|
31
|
+
|
32
|
+
# @!scope class
|
33
|
+
# @!method versions
|
34
|
+
# @return [ActiveRecord<Object>]
|
35
|
+
#
|
36
|
+
# Returns only +versions+ of the parent +ActiveRecord+ class, cast as instances of the source
|
37
|
+
# model’s class.
|
20
38
|
scope :versions, -> { include_versions.where(TABLEOID_AREL_CONDITIONS.call(arel_table, :not_eq)) }
|
21
39
|
end
|
22
40
|
|
41
|
+
private
|
42
|
+
|
23
43
|
def tableoid
|
24
44
|
connection.execute("SELECT oid FROM pg_class WHERE relname = '#{table_name}'")[0]['oid']
|
25
45
|
end
|
data/lib/hoardable/version.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Hoardable
|
4
|
-
# This concern is included into the dynamically generated Version
|
4
|
+
# This concern is included into the dynamically generated +Version+ kind of the parent
|
5
|
+
# +ActiveRecord+ class.
|
5
6
|
module VersionModel
|
6
7
|
extend ActiveSupport::Concern
|
7
8
|
|
8
9
|
included do
|
9
10
|
hoardable_source_key = superclass.model_name.i18n_key
|
11
|
+
|
12
|
+
# A +version+ belongs to it’s parent +ActiveRecord+ source.
|
10
13
|
belongs_to hoardable_source_key, inverse_of: :versions
|
11
14
|
alias_method :hoardable_source, hoardable_source_key
|
12
15
|
|
@@ -19,15 +22,35 @@ module Hoardable
|
|
19
22
|
|
20
23
|
before_create :assign_temporal_tsrange
|
21
24
|
|
25
|
+
# @!scope class
|
26
|
+
# @!method trashed
|
27
|
+
# @return [ActiveRecord<Object>]
|
28
|
+
#
|
29
|
+
# Returns only trashed +versions+ that are orphans.
|
22
30
|
scope :trashed, lambda {
|
23
31
|
left_outer_joins(hoardable_source_key)
|
24
32
|
.where(superclass.table_name => { id: nil })
|
25
33
|
.where(_operation: 'delete')
|
26
34
|
}
|
35
|
+
|
36
|
+
# @!scope class
|
37
|
+
# @!method at
|
38
|
+
# @return [ActiveRecord<Object>]
|
39
|
+
#
|
40
|
+
# Returns +versions+ that were valid at the supplied +datetime+ or +time+.
|
27
41
|
scope :at, ->(datetime) { where(DURING_QUERY, datetime) }
|
42
|
+
|
43
|
+
# @!scope class
|
44
|
+
# @!method with_hoardable_event_uuid
|
45
|
+
# @return [ActiveRecord<Object>]
|
46
|
+
#
|
47
|
+
# Returns all +versions+ that were created as part of the same +ActiveRecord+ database
|
48
|
+
# transaction of the supplied +event_uuid+. Useful in +reverted+ and +untrashed+ callbacks.
|
28
49
|
scope :with_hoardable_event_uuid, ->(event_uuid) { where(_event_uuid: event_uuid) }
|
29
50
|
end
|
30
51
|
|
52
|
+
# Reverts the parent +ActiveRecord+ instance to the saved attributes of this +version+. Raises
|
53
|
+
# an error if the version is trashed.
|
31
54
|
def revert!
|
32
55
|
raise(Error, 'Version is trashed, cannot revert') unless hoardable_operation == 'update'
|
33
56
|
|
@@ -40,6 +63,8 @@ module Hoardable
|
|
40
63
|
end
|
41
64
|
end
|
42
65
|
|
66
|
+
# Inserts a trashed +version+ back into its parent +ActiveRecord+ table with its original
|
67
|
+
# primary key. Raises an error if the version is not trashed.
|
43
68
|
def untrash!
|
44
69
|
raise(Error, 'Version is not trashed, cannot untrash') unless hoardable_operation == 'delete'
|
45
70
|
|
@@ -59,6 +84,9 @@ module Hoardable
|
|
59
84
|
end
|
60
85
|
end
|
61
86
|
|
87
|
+
# Returns the +ActiveRecord+
|
88
|
+
# {https://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes changes} that
|
89
|
+
# were present during version creation.
|
62
90
|
def changes
|
63
91
|
_data&.dig('changes')
|
64
92
|
end
|
data/sig/hoardable.rbs
CHANGED
@@ -1,4 +1,86 @@
|
|
1
1
|
module Hoardable
|
2
2
|
VERSION: String
|
3
|
-
|
3
|
+
DATA_KEYS: [:meta, :whodunit, :note, :event_uuid]
|
4
|
+
CONFIG_KEYS: [:enabled, :version_updates, :save_trash]
|
5
|
+
VERSION_CLASS_SUFFIX: String
|
6
|
+
VERSION_TABLE_SUFFIX: String
|
7
|
+
DURING_QUERY: String
|
8
|
+
self.@context: Hash[untyped, untyped]
|
9
|
+
self.@config: untyped
|
10
|
+
|
11
|
+
def self.with: (untyped hash) -> untyped
|
12
|
+
|
13
|
+
module Tableoid
|
14
|
+
TABLEOID_AREL_CONDITIONS: Proc
|
15
|
+
|
16
|
+
private
|
17
|
+
def tableoid: -> untyped
|
18
|
+
|
19
|
+
public
|
20
|
+
attr_writer tableoid: untyped
|
21
|
+
end
|
22
|
+
|
23
|
+
class Error < StandardError
|
24
|
+
end
|
25
|
+
|
26
|
+
module SourceModel
|
27
|
+
include Tableoid
|
28
|
+
|
29
|
+
def trashed?: -> untyped
|
30
|
+
def at: (untyped datetime) -> SourceModel
|
31
|
+
def revert_to!: (untyped datetime) -> SourceModel?
|
32
|
+
|
33
|
+
private
|
34
|
+
def hoardable_callbacks_enabled: -> untyped
|
35
|
+
def hoardable_save_trash: -> untyped
|
36
|
+
def hoardable_version_updates: -> untyped
|
37
|
+
def insert_hoardable_version_on_update: -> untyped
|
38
|
+
def insert_hoardable_version_on_destroy: -> untyped
|
39
|
+
def insert_hoardable_version: (String operation, untyped attrs) -> untyped
|
40
|
+
def find_or_initialize_hoardable_event_uuid: -> untyped
|
41
|
+
def initialize_hoardable_version: (String operation, untyped attrs) -> untyped
|
42
|
+
def initialize_hoardable_data: -> untyped
|
43
|
+
def assign_hoardable_context: (:event_uuid | :meta | :note | :whodunit key) -> nil
|
44
|
+
def delete_hoardable_versions: -> untyped
|
45
|
+
def unset_hoardable_version_and_event_uuid: -> nil
|
46
|
+
|
47
|
+
public
|
48
|
+
def version_class: -> untyped
|
49
|
+
attr_reader hoardable_version: nil
|
50
|
+
end
|
51
|
+
|
52
|
+
module VersionModel
|
53
|
+
@hoardable_source_attributes: untyped
|
54
|
+
@hoardable_source_foreign_key: String
|
55
|
+
@hoardable_source_foreign_id: untyped
|
56
|
+
|
57
|
+
def revert!: -> untyped
|
58
|
+
def untrash!: -> untyped
|
59
|
+
def changes: -> untyped
|
60
|
+
|
61
|
+
private
|
62
|
+
def untrashable_hoardable_source_attributes: -> untyped
|
63
|
+
def hoardable_source_attributes: -> untyped
|
64
|
+
def hoardable_source_foreign_key: -> String
|
65
|
+
def hoardable_source_foreign_id: -> untyped
|
66
|
+
def previous_temporal_tsrange_end: -> untyped
|
67
|
+
def assign_temporal_tsrange: -> Range
|
68
|
+
end
|
69
|
+
|
70
|
+
module Model
|
71
|
+
include VersionModel
|
72
|
+
include SourceModel
|
73
|
+
|
74
|
+
attr_reader _hoardable_options: Hash[untyped, untyped]
|
75
|
+
def hoardable_options: (?nil hash) -> untyped
|
76
|
+
end
|
77
|
+
|
78
|
+
class MigrationGenerator
|
79
|
+
@singularized_table_name: untyped
|
80
|
+
|
81
|
+
def create_versions_table: -> untyped
|
82
|
+
def foreign_key_type: -> String
|
83
|
+
def migration_template_name: -> String
|
84
|
+
def singularized_table_name: -> untyped
|
85
|
+
end
|
4
86
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hoardable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- justin talbott
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|