hoardable 0.1.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +108 -16
- data/lib/hoardable/hoardable.rb +3 -6
- data/lib/hoardable/model.rb +36 -0
- data/lib/hoardable/source_model.rb +13 -5
- data/lib/hoardable/tableoid.rb +10 -3
- data/lib/hoardable/version.rb +1 -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: 50086ef99aac41454b28ab8bff2e8abf94d7870b371da0c706c477e0b296ffc3
|
4
|
+
data.tar.gz: 6e6d4ab40470bbfb93e23e96fdbb2d8b086878d24e55d499ac368523125e5397
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 747ac52845c950eb655cb7b0af22794dda49ed08e2b0f1aee472595fd2c63b1f886d4f516e686807607efe4946ca588792913ea92ec1c3152a44c23f8cd84487
|
7
|
+
data.tar.gz: 3460ccd66ebe6eed7cdb129bca6150696b82ad9f8613965e80b08fb458ac6e2b8b644e662036533f73f95f52b97a10bf50f2782f76d3fd6671f23f9c2b58df08
|
data/README.md
CHANGED
@@ -3,10 +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
|
-
[👉 Documentation](https://www.rubydoc.info/gems/hoardable)
|
7
|
-
|
8
|
-
### huh?
|
9
|
-
|
10
6
|
[Temporal tables](https://en.wikipedia.org/wiki/Temporal_database) are a database design pattern
|
11
7
|
where each row of a table contains data along with one or more time ranges. In the case of this gem,
|
12
8
|
each database row has a time range that represents the row’s valid time range - hence
|
@@ -20,8 +16,10 @@ change is reflected on its descendants.
|
|
20
16
|
With these concepts combined, `hoardable` offers a simple and effective model versioning system for
|
21
17
|
Rails. Versions of records are stored in separate, inherited tables along with their valid time
|
22
18
|
ranges and contextual data. Compared to other Rails-oriented versioning systems, this gem strives to
|
23
|
-
be more explicit and obvious on the lower RDBS level while still familiar and convenient
|
24
|
-
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)
|
25
23
|
|
26
24
|
## Installation
|
27
25
|
|
@@ -71,7 +69,7 @@ Rails 7.
|
|
71
69
|
### Overview
|
72
70
|
|
73
71
|
Once you include `Hoardable::Model` into a model, it will dynamically generate a "Version" subclass
|
74
|
-
of that model. As we continue our example above
|
72
|
+
of that model. As we continue our example above:
|
75
73
|
|
76
74
|
```
|
77
75
|
$ irb
|
@@ -119,6 +117,10 @@ post.at(1.day.ago) # => #<PostVersion:0x000000010d44fa30>
|
|
119
117
|
PostVersion.at(1.day.ago).find_by(post_id: post.id) # => #<PostVersion:0x000000010d44fa30>
|
120
118
|
```
|
121
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
|
+
|
122
124
|
By default, `hoardable` will keep copies of records you have destroyed. You can query for them as
|
123
125
|
well:
|
124
126
|
|
@@ -129,7 +131,7 @@ PostVersion.trashed
|
|
129
131
|
_Note:_ Creating an inherited table does not copy over the indexes from the parent table. If you
|
130
132
|
need to query versions often, you should add appropriate indexes to the `_versions` tables.
|
131
133
|
|
132
|
-
### Tracking
|
134
|
+
### Tracking Contextual Data
|
133
135
|
|
134
136
|
You’ll often want to track contextual data about the creation of a version. There are 3 optional
|
135
137
|
symbol keys that are provided for tracking contextual information:
|
@@ -144,7 +146,10 @@ choosing.
|
|
144
146
|
One convenient way to assign contextual data to these is by defining a proc in an initializer, i.e.:
|
145
147
|
|
146
148
|
```ruby
|
149
|
+
# config/initiailzers/hoardable.rb
|
147
150
|
Hoardable.whodunit = -> { Current.user&.id }
|
151
|
+
|
152
|
+
# somewhere in your app code
|
148
153
|
Current.user = User.find(123)
|
149
154
|
post.update!(status: 'live')
|
150
155
|
post.versions.last.hoardable_whodunit # => 123
|
@@ -222,19 +227,27 @@ end
|
|
222
227
|
|
223
228
|
### Configuration
|
224
229
|
|
225
|
-
There are
|
230
|
+
There are three configurable options currently:
|
226
231
|
|
227
232
|
```ruby
|
228
233
|
Hoardable.enabled # => default true
|
234
|
+
Hoardable.version_updates # => default true
|
229
235
|
Hoardable.save_trash # => default true
|
236
|
+
Hoardable.return_everything # => default false
|
230
237
|
```
|
231
238
|
|
232
|
-
`Hoardable.enabled` controls whether versions will be
|
239
|
+
`Hoardable.enabled` controls whether versions will be ever be created.
|
240
|
+
|
241
|
+
`Hoardable.version_updates` controls whether versions get created on record updates.
|
233
242
|
|
234
243
|
`Hoardable.save_trash` controls whether to create versions upon record deletion. When this is set to
|
235
244
|
`false`, all versions of a record will be deleted when the record is destroyed.
|
236
245
|
|
237
|
-
|
246
|
+
`Hoardable.return_everything` controls whether to include versions when doing queries for source
|
247
|
+
models. This is typically only useful to set around a block, as explained below in
|
248
|
+
[Relationships](#relationships).
|
249
|
+
|
250
|
+
If you would like to temporarily set a config setting, you can use `Hoardable.with`:
|
238
251
|
|
239
252
|
```ruby
|
240
253
|
Hoardable.with(enabled: false) do
|
@@ -242,6 +255,27 @@ Hoardable.with(enabled: false) do
|
|
242
255
|
end
|
243
256
|
```
|
244
257
|
|
258
|
+
You can also configure these variables per `ActiveRecord` class as well using `hoardable_config`:
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
class Comment < ActiveRecord::Base
|
262
|
+
include Hoardable::Model
|
263
|
+
hoardable_config version_updates: false
|
264
|
+
end
|
265
|
+
```
|
266
|
+
|
267
|
+
If you want to temporarily set the `hoardable_config` for a specific model, you can use
|
268
|
+
`with_hoardable_config`:
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
Comment.with_hoardable_config(version_updates: true) do
|
272
|
+
comment.update!(text: "Edited")
|
273
|
+
end
|
274
|
+
```
|
275
|
+
|
276
|
+
If a model-level option exists, it will use that. Otherwise, it will fall back to the global
|
277
|
+
`Hoardable` config.
|
278
|
+
|
245
279
|
### Relationships
|
246
280
|
|
247
281
|
As in life, sometimes relationships can be hard. `hoardable` is still working out best practices and
|
@@ -250,17 +284,20 @@ features in this area, but here are a couple pointers.
|
|
250
284
|
Sometimes you’ll have a record that belongs to a record that you’ll trash. Now the child record’s
|
251
285
|
foreign key will point to the non-existent trashed version of the parent. If you would like this
|
252
286
|
`belongs_to` relationship to always resolve to the parent as if it was not trashed, you can include
|
253
|
-
the scope on the relationship definition:
|
287
|
+
the `include_versions` scope on the relationship definition:
|
254
288
|
|
255
289
|
```ruby
|
256
|
-
|
290
|
+
class Comment
|
291
|
+
include Hoardable::Model
|
292
|
+
belongs_to :post, -> { include_versions } # `Post` also includes `Hoardable::Model`
|
293
|
+
end
|
257
294
|
```
|
258
295
|
|
259
296
|
Sometimes you’ll trash something that `has_many :children, dependent: :destroy` and both the parent
|
260
297
|
and child model classes include `Hoardable::Model`. Whenever a hoardable version is created in a
|
261
298
|
database transaction, it will create or re-use a unique event UUID for that transaction and tag all
|
262
|
-
versions created with it. That way, when you `untrash!` a
|
263
|
-
|
299
|
+
versions created with it. That way, when you `untrash!` a record, you can find and `untrash!`
|
300
|
+
records that were trashed with it:
|
264
301
|
|
265
302
|
```ruby
|
266
303
|
class Post < ActiveRecord::Base
|
@@ -278,9 +315,64 @@ class Post < ActiveRecord::Base
|
|
278
315
|
end
|
279
316
|
```
|
280
317
|
|
318
|
+
If there are models that might be related to versions that are trashed or otherwise, and/or might
|
319
|
+
trashed themselves, you can bypass the inherited tables query handling altogether by using the
|
320
|
+
`return_everything` configuration variable in `Hoardable.with`:
|
321
|
+
|
322
|
+
```ruby
|
323
|
+
post.destroy!
|
324
|
+
|
325
|
+
Hoardable.with(return_everything: true) do
|
326
|
+
post = Post.find(post.id) # returns the trashed post as if it was not
|
327
|
+
post.comments # returns the trashed comments as well
|
328
|
+
end
|
329
|
+
|
330
|
+
post.reload # raises ActiveRecord::RecordNotFound
|
331
|
+
```
|
332
|
+
|
333
|
+
## Gem Comparison
|
334
|
+
|
335
|
+
### [`paper_trail`](https://github.com/paper-trail-gem/paper_trail)
|
336
|
+
|
337
|
+
`paper_trail` is maybe the most popular and fully featured gem in this space. It works for other
|
338
|
+
database types than PostgeSQL and (by default) stores all versions of all versioned models in a
|
339
|
+
single `versions` table. It stores changes in a `text`, `json`, or `jsonb` column. In order to
|
340
|
+
efficiently query the `versions` table, a `jsonb` column should be used, which takes up a lot of
|
341
|
+
space to index. Unless you customize your configuration, all `versions` for all models types are
|
342
|
+
in the same table which is inefficient if you are only interested in querying versions of a single
|
343
|
+
model. By contrast, `hoardable` stores versions in smaller, isolated and inherited tables with the
|
344
|
+
same database columns as their parents, which are more efficient for querying as well as auditing
|
345
|
+
for truncating and dropping. The concept of a `temporal` time-frame does not exist for a single
|
346
|
+
version since there is only a `created_at` timestamp.
|
347
|
+
|
348
|
+
### [`audited`](https://github.com/collectiveidea/audited)
|
349
|
+
|
350
|
+
`audited` works in a similar manner as `paper_trail`. It stores all versions for all model types in
|
351
|
+
a single table, you must opt into using `jsonb` as the column type to store "changes", in case you
|
352
|
+
want to query them, and there is no concept of a `temporal` time-frame for a single version. It
|
353
|
+
makes opinionated decisions about contextual data requirements and stores them as top level data
|
354
|
+
types on the `audited` table.
|
355
|
+
|
356
|
+
### [`discard`](https://github.com/jhawthorn/discard)
|
357
|
+
|
358
|
+
`discard` only covers soft-deletion. The act of "soft deleting" a record is only captured through
|
359
|
+
the time-stamping of a `discarded_at` column on the records table; there is no other capturing of
|
360
|
+
the event that caused the soft deletion unless you implement it yourself. Once the "discarded"
|
361
|
+
record is restored, the previous "discarded" awareness is lost. Since "discarded" records exist in
|
362
|
+
the same table as "undiscarded" records, you must explicitly omit the discarded records from queries
|
363
|
+
across your app to keep them from leaking in.
|
364
|
+
|
365
|
+
### [`paranoia`](https://github.com/rubysherpas/paranoia)
|
366
|
+
|
367
|
+
`paranoia` also only covers soft-deletion. In their README, they recommend using `discard` instead
|
368
|
+
of `paranoia` because of the fact they override ActiveRecord’s `delete` and `destroy` methods.
|
369
|
+
`hoardable` employs callbacks to create trashed versions instead of overriding methods. Otherwise,
|
370
|
+
`paranoia` works similarly to `discard` in that it keeps deleted records in the same table and tags
|
371
|
+
them with a `deleted_at` timestamp. No other information about the soft-deletion event is stored.
|
372
|
+
|
281
373
|
## Contributing
|
282
374
|
|
283
|
-
This gem
|
375
|
+
This gem still quite new and very open to feedback.
|
284
376
|
|
285
377
|
Bug reports and pull requests are welcome on GitHub at https://github.com/waymondo/hoardable.
|
286
378
|
|
data/lib/hoardable/hoardable.rb
CHANGED
@@ -7,7 +7,7 @@ module Hoardable
|
|
7
7
|
DATA_KEYS = %i[meta whodunit note event_uuid].freeze
|
8
8
|
# Symbols for use with setting {Hoardable} configuration. See {file:README.md#configuration
|
9
9
|
# README} for more.
|
10
|
-
CONFIG_KEYS = %i[enabled save_trash].freeze
|
10
|
+
CONFIG_KEYS = %i[enabled version_updates save_trash return_everything].freeze
|
11
11
|
|
12
12
|
# @!visibility private
|
13
13
|
VERSION_CLASS_SUFFIX = 'Version'
|
@@ -15,15 +15,12 @@ module Hoardable
|
|
15
15
|
# @!visibility private
|
16
16
|
VERSION_TABLE_SUFFIX = "_#{VERSION_CLASS_SUFFIX.tableize}"
|
17
17
|
|
18
|
-
# @!visibility private
|
19
|
-
SAVE_TRASH_ENABLED = -> { Hoardable.save_trash }.freeze
|
20
|
-
|
21
18
|
# @!visibility private
|
22
19
|
DURING_QUERY = '_during @> ?::timestamp'
|
23
20
|
|
24
21
|
@context = {}
|
25
22
|
@config = CONFIG_KEYS.to_h do |key|
|
26
|
-
[key,
|
23
|
+
[key, key != :return_everything]
|
27
24
|
end
|
28
25
|
|
29
26
|
class << self
|
@@ -49,7 +46,7 @@ module Hoardable
|
|
49
46
|
|
50
47
|
# This is a general use method for setting {DATA_KEYS} or {CONFIG_KEYS} around a scoped block.
|
51
48
|
#
|
52
|
-
# @param hash [Hash]
|
49
|
+
# @param hash [Hash] config and contextual data to set within a block
|
53
50
|
def with(hash)
|
54
51
|
current_config = @config
|
55
52
|
current_context = @context
|
data/lib/hoardable/model.rb
CHANGED
@@ -8,6 +8,42 @@ module Hoardable
|
|
8
8
|
module Model
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
11
|
+
class_methods do
|
12
|
+
# @!visibility private
|
13
|
+
attr_reader :_hoardable_config
|
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_config(hash = nil)
|
23
|
+
if hash
|
24
|
+
@_hoardable_config = hash.slice(*Hoardable::CONFIG_KEYS)
|
25
|
+
else
|
26
|
+
@_hoardable_config ||= {}
|
27
|
+
Hoardable::CONFIG_KEYS.to_h do |key|
|
28
|
+
[key, @_hoardable_config.key?(key) ? @_hoardable_config[key] : Hoardable.send(key)]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Set the model-level +Hoardable+ configuration variables around a block. The configuration
|
34
|
+
# will be reset to it’s previous value afterwards.
|
35
|
+
#
|
36
|
+
# @param hash [Hash] The +Hoardable+ configuration for the model. Keys must be present in
|
37
|
+
# {CONFIG_KEYS}
|
38
|
+
def with_hoardable_config(hash)
|
39
|
+
current_config = @_hoardable_config
|
40
|
+
@_hoardable_config = hash.slice(*Hoardable::CONFIG_KEYS)
|
41
|
+
yield
|
42
|
+
ensure
|
43
|
+
@_hoardable_config = current_config
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
11
47
|
included do
|
12
48
|
define_model_callbacks :versioned
|
13
49
|
define_model_callbacks :reverted, only: :after
|
@@ -17,9 +17,9 @@ module Hoardable
|
|
17
17
|
included do
|
18
18
|
include Tableoid
|
19
19
|
|
20
|
-
around_update :insert_hoardable_version_on_update, if:
|
21
|
-
around_destroy :insert_hoardable_version_on_destroy, if: [
|
22
|
-
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
|
23
23
|
after_commit :unset_hoardable_version_and_event_uuid
|
24
24
|
|
25
25
|
# This will contain the +Version+ class instance for use within +versioned+, +reverted+, and
|
@@ -45,7 +45,7 @@ module Hoardable
|
|
45
45
|
#
|
46
46
|
# @return [Boolean]
|
47
47
|
def trashed?
|
48
|
-
versions.trashed.limit(1).order(_during: :desc).first&.
|
48
|
+
versions.trashed.limit(1).order(_during: :desc).first&.id == id
|
49
49
|
end
|
50
50
|
|
51
51
|
# Returns the +version+ at the supplied +datetime+ or +time+. It will return +self+ if there is
|
@@ -71,7 +71,15 @@ module Hoardable
|
|
71
71
|
private
|
72
72
|
|
73
73
|
def hoardable_callbacks_enabled
|
74
|
-
|
74
|
+
self.class.hoardable_config[:enabled] && !self.class.name.end_with?(VERSION_CLASS_SUFFIX)
|
75
|
+
end
|
76
|
+
|
77
|
+
def hoardable_save_trash
|
78
|
+
self.class.hoardable_config[:save_trash]
|
79
|
+
end
|
80
|
+
|
81
|
+
def hoardable_version_updates
|
82
|
+
self.class.hoardable_config[:version_updates]
|
75
83
|
end
|
76
84
|
|
77
85
|
def insert_hoardable_version_on_update(&block)
|
data/lib/hoardable/tableoid.rb
CHANGED
@@ -17,9 +17,16 @@ module Hoardable
|
|
17
17
|
# @!visibility private
|
18
18
|
attr_writer :tableoid
|
19
19
|
|
20
|
-
# By default
|
21
|
-
#
|
22
|
-
|
20
|
+
# By default {Hoardable} only returns instances of the parent table, and not the +versions+ in
|
21
|
+
# the inherited table. This can be bypassed by using the {.include_versions} scope or wrapping
|
22
|
+
# the code in a `Hoardable.with(return_everything: true)` block.
|
23
|
+
default_scope do
|
24
|
+
if hoardable_config[:return_everything]
|
25
|
+
where(nil)
|
26
|
+
else
|
27
|
+
where(TABLEOID_AREL_CONDITIONS.call(arel_table, :eq))
|
28
|
+
end
|
29
|
+
end
|
23
30
|
|
24
31
|
# @!scope class
|
25
32
|
# @!method include_versions
|
data/lib/hoardable/version.rb
CHANGED
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, :return_everything]
|
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
|
+
def hoardable_config: (?nil hash) -> untyped
|
75
|
+
def with_hoardable_config: (untyped 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.3.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-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|