hoardable 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c4bc9bc4cdd73263a6afe5551b59f085cbf7dc3877e472df8abdba62f5fcbd6
4
- data.tar.gz: 7aa8ea828b2f6083a80c93e34a1fcc5756508db15f2a317dc95bfea2ae8b1e28
3
+ metadata.gz: dff71dd2ebbebaeedfdc9d6fdd8c56c8faaa5505814cfe41c146c4a565375ff1
4
+ data.tar.gz: 6693f3634541bc8308ed5b4329d69851d971df1cec2b50e842fa9332c62425b6
5
5
  SHA512:
6
- metadata.gz: 915cba36e937b34667b2ad31ae8dd780224a417669a6bb3c1abdfb2c8a19c10525e7d29a0a4f264aa475362f9b823104bd5a40d71bfc01848db2eb6a463f7c1d
7
- data.tar.gz: ab0faaab94b03c5b6452b7aad505e16b4bb98538ae8649cfd65e17d397e3d917e6e61c752ed39b820dc30d72503e993ec5d6fbe353391c29025759a4bedeff74
6
+ metadata.gz: ec2a9df9254cf3623f4fffb0516e99ec30a46ec6496ad0d5e555d4a3ce8324fa81d1880036f42aeb4bbbee136957479f283ccab4b8fb3f2847122bd597483889
7
+ data.tar.gz: 25a5040c6dc5b91b0b54020657e436aa775cf2211b56fecf1b277e36c11041b55f5a29861000503d5388a9a3d0280a8ccca99c052a2dc82a45abb8f5c98bb50e
data/.rubocop.yml CHANGED
@@ -10,5 +10,9 @@ Metrics/ClassLength:
10
10
  Exclude:
11
11
  - 'test/**/*.rb'
12
12
 
13
+ Metrics/BlockLength:
14
+ Exclude:
15
+ - 'test/**/*.rb'
16
+
13
17
  Style/DocumentDynamicEvalDefinition:
14
18
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.0] - 2022-09-28
4
+
5
+ - **Breaking Change** - Previously, a source model would `has_many :versions` with an inverse
6
+ relationship of the i18n interpreted name of the source model. Now it simply `has_many :versions,
7
+ inverse_of :hoardable_source` to not potentially conflict with previously existing relationships.
8
+
3
9
  ## [0.5.0] - 2022-09-25
4
10
 
5
11
  - **Breaking Change** - Untrashing a version will now insert a version for the untrash event with
@@ -8,7 +8,7 @@ module Hoardable
8
8
 
9
9
  # Symbols for use with setting {Hoardable} configuration. See {file:README.md#configuration
10
10
  # README} for more.
11
- CONFIG_KEYS = %i[enabled version_updates save_trash return_everything].freeze
11
+ CONFIG_KEYS = %i[enabled version_updates save_trash return_everything warn_on_missing_created_at_column].freeze
12
12
 
13
13
  VERSION_CLASS_SUFFIX = 'Version'
14
14
  private_constant :VERSION_CLASS_SUFFIX
@@ -19,6 +19,21 @@ module Hoardable
19
19
  DURING_QUERY = '_during @> ?::timestamp'
20
20
  private_constant :DURING_QUERY
21
21
 
22
+ HOARDABLE_CALLBACKS_ENABLED = proc do |source_model|
23
+ source_model.class.hoardable_config[:enabled] && !source_model.class.name.end_with?(VERSION_CLASS_SUFFIX)
24
+ end.freeze
25
+ private_constant :HOARDABLE_CALLBACKS_ENABLED
26
+
27
+ HOARDABLE_SAVE_TRASH = proc do |source_model|
28
+ source_model.class.hoardable_config[:save_trash]
29
+ end.freeze
30
+ private_constant :HOARDABLE_SAVE_TRASH
31
+
32
+ HOARDABLE_VERSION_UPDATES = proc do |source_model|
33
+ source_model.class.hoardable_config[:version_updates]
34
+ end.freeze
35
+ private_constant :HOARDABLE_VERSION_UPDATES
36
+
22
37
  @context = {}
23
38
  @config = CONFIG_KEYS.to_h do |key|
24
39
  [key, key != :return_everything]
@@ -59,5 +74,10 @@ module Hoardable
59
74
  @config = current_config
60
75
  @context = current_context
61
76
  end
77
+
78
+ # @!visibility private
79
+ def logger
80
+ @logger ||= ActiveSupport::TaggedLogging.new(Logger.new($stdout))
81
+ end
62
82
  end
63
83
  end
@@ -7,6 +7,15 @@ module Hoardable
7
7
  module SourceModel
8
8
  extend ActiveSupport::Concern
9
9
 
10
+ # The +Version+ class instance for use within +versioned+, +reverted+, and +untrashed+ callbacks.
11
+ attr_reader :hoardable_version
12
+
13
+ # @!attribute [r] hoardable_event_uuid
14
+ # @return [String] A postgres UUID that represents the +version+’s +ActiveRecord+ database transaction
15
+ # @!attribute [r] hoardable_operation
16
+ # @return [String] The database operation that created the +version+ - either +update+ or +delete+.
17
+ delegate :hoardable_event_uuid, :hoardable_operation, to: :hoardable_version, allow_nil: true
18
+
10
19
  class_methods do
11
20
  # The dynamically generated +Version+ class for this model.
12
21
  def version_class
@@ -17,27 +26,26 @@ module Hoardable
17
26
  included do
18
27
  include Tableoid
19
28
 
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
- after_commit :unset_hoardable_version_and_event_uuid
29
+ around_update(if: [HOARDABLE_CALLBACKS_ENABLED, HOARDABLE_VERSION_UPDATES]) do |_, block|
30
+ hoardable_source_service.insert_hoardable_version('update', &block)
31
+ end
24
32
 
25
- # This will contain the +Version+ class instance for use within +versioned+, +reverted+, and
26
- # +untrashed+ callbacks.
27
- attr_reader :hoardable_version
33
+ around_destroy(if: [HOARDABLE_CALLBACKS_ENABLED, HOARDABLE_SAVE_TRASH]) do |_, block|
34
+ hoardable_source_service.insert_hoardable_version('delete', &block)
35
+ end
28
36
 
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+.
33
- delegate :hoardable_event_uuid, :hoardable_operation, to: :hoardable_version, allow_nil: true
37
+ before_destroy(if: HOARDABLE_CALLBACKS_ENABLED, unless: HOARDABLE_SAVE_TRASH) do
38
+ versions.delete_all(:delete_all)
39
+ end
40
+
41
+ after_commit { hoardable_source_service.unset_hoardable_version_and_event_uuid }
34
42
 
35
43
  # Returns all +versions+ in ascending order of their temporal timeframes.
36
44
  has_many(
37
45
  :versions, -> { order('UPPER(_during) ASC') },
38
46
  dependent: nil,
39
47
  class_name: version_class.to_s,
40
- inverse_of: model_name.i18n_key
48
+ inverse_of: :hoardable_source
41
49
  )
42
50
 
43
51
  # @!scope class
@@ -47,11 +55,8 @@ module Hoardable
47
55
  # Returns instances of the source model and versions that were valid at the supplied
48
56
  # +datetime+ or +time+, all cast as instances of the source model.
49
57
  scope :at, lambda { |datetime|
50
- versioned = version_class.at(datetime)
51
- trashed = version_class.trashed_at(datetime)
52
- foreign_key = version_class.hoardable_source_foreign_key
53
- include_versions.where(id: versioned.select('id')).or(
54
- where.not(id: versioned.select(foreign_key)).where.not(id: trashed.select(foreign_key))
58
+ include_versions.where(id: version_class.at(datetime).select('id')).or(
59
+ where.not(id: version_class.select(version_class.hoardable_source_foreign_key).where(DURING_QUERY, datetime))
55
60
  )
56
61
  }
57
62
  end
@@ -70,7 +75,7 @@ module Hoardable
70
75
  def at(datetime)
71
76
  raise(Error, 'Future state cannot be known') if datetime.future?
72
77
 
73
- versions.find_by(DURING_QUERY, datetime) || self
78
+ versions.at(datetime).first || self
74
79
  end
75
80
 
76
81
  # If a version is found at the supplied datetime, it will +revert!+ to it and return it. This
@@ -85,76 +90,63 @@ module Hoardable
85
90
 
86
91
  private
87
92
 
88
- def hoardable_callbacks_enabled
89
- self.class.hoardable_config[:enabled] && !self.class.name.end_with?(VERSION_CLASS_SUFFIX)
90
- end
91
-
92
- def hoardable_save_trash
93
- self.class.hoardable_config[:save_trash]
94
- end
95
-
96
- def hoardable_version_updates
97
- self.class.hoardable_config[:version_updates]
93
+ def hoardable_source_service
94
+ @hoardable_source_service ||= Service.new(self)
98
95
  end
99
96
 
100
- def insert_hoardable_version_on_update(&block)
101
- insert_hoardable_version('update', &block)
102
- end
97
+ # This is a private service class that manages the insertion of {VersionModel}s for a
98
+ # {SourceModel} into the PostgreSQL database.
99
+ class Service
100
+ attr_reader :source_model
103
101
 
104
- def insert_hoardable_version_on_destroy(&block)
105
- insert_hoardable_version('delete', &block)
106
- end
107
-
108
- def insert_hoardable_version_on_untrashed
109
- initialize_hoardable_version('insert').save(validate: false, touch: false)
110
- end
102
+ def initialize(source_model)
103
+ @source_model = source_model
104
+ end
111
105
 
112
- def insert_hoardable_version(operation)
113
- @hoardable_version = initialize_hoardable_version(operation)
114
- run_callbacks(:versioned) do
115
- yield
116
- hoardable_version.save(validate: false, touch: false)
106
+ def insert_hoardable_version(operation)
107
+ source_model.instance_variable_set('@hoardable_version', initialize_hoardable_version(operation))
108
+ source_model.run_callbacks(:versioned) do
109
+ yield if block_given?
110
+ source_model.hoardable_version.save(validate: false, touch: false)
111
+ end
117
112
  end
118
- end
119
113
 
120
- def find_or_initialize_hoardable_event_uuid
121
- Thread.current[:hoardable_event_uuid] ||= ActiveRecord::Base.connection.query('SELECT gen_random_uuid();')[0][0]
122
- end
114
+ def find_or_initialize_hoardable_event_uuid
115
+ Thread.current[:hoardable_event_uuid] ||= ActiveRecord::Base.connection.query('SELECT gen_random_uuid();')[0][0]
116
+ end
123
117
 
124
- def initialize_hoardable_version(operation)
125
- versions.new(
126
- attributes_before_type_cast.without('id').merge(
127
- changes.transform_values { |h| h[0] },
128
- {
129
- _event_uuid: find_or_initialize_hoardable_event_uuid,
130
- _operation: operation,
131
- _data: initialize_hoardable_data.merge(changes: changes)
132
- }
118
+ def initialize_hoardable_version(operation)
119
+ source_model.versions.new(
120
+ source_model.attributes_before_type_cast.without('id').merge(
121
+ source_model.changes.transform_values { |h| h[0] },
122
+ {
123
+ _event_uuid: find_or_initialize_hoardable_event_uuid,
124
+ _operation: operation,
125
+ _data: initialize_hoardable_data.merge(changes: source_model.changes)
126
+ }
127
+ )
133
128
  )
134
- )
135
- end
136
-
137
- def initialize_hoardable_data
138
- DATA_KEYS.to_h do |key|
139
- [key, assign_hoardable_context(key)]
140
129
  end
141
- end
142
130
 
143
- def assign_hoardable_context(key)
144
- return nil if (value = Hoardable.public_send(key)).nil?
131
+ def initialize_hoardable_data
132
+ DATA_KEYS.to_h do |key|
133
+ [key, assign_hoardable_context(key)]
134
+ end
135
+ end
145
136
 
146
- value.is_a?(Proc) ? value.call : value
147
- end
137
+ def assign_hoardable_context(key)
138
+ return nil if (value = Hoardable.public_send(key)).nil?
148
139
 
149
- def delete_hoardable_versions
150
- versions.delete_all(:delete_all)
151
- end
140
+ value.is_a?(Proc) ? value.call : value
141
+ end
152
142
 
153
- def unset_hoardable_version_and_event_uuid
154
- @hoardable_version = nil
155
- return if ActiveRecord::Base.connection.transaction_open?
143
+ def unset_hoardable_version_and_event_uuid
144
+ source_model.instance_variable_set('@hoardable_version', nil)
145
+ return if source_model.class.connection.transaction_open?
156
146
 
157
- Thread.current[:hoardable_event_uuid] = nil
147
+ Thread.current[:hoardable_event_uuid] = nil
148
+ end
158
149
  end
150
+ private_constant :Service
159
151
  end
160
152
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hoardable
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.0'
5
5
  end
@@ -14,11 +14,13 @@ module Hoardable
14
14
  end
15
15
 
16
16
  included do
17
- hoardable_source_key = superclass.model_name.i18n_key
18
-
19
17
  # A +version+ belongs to it’s parent +ActiveRecord+ source.
20
- belongs_to hoardable_source_key, inverse_of: :versions
21
- alias_method :hoardable_source, hoardable_source_key
18
+ belongs_to(
19
+ :hoardable_source,
20
+ inverse_of: :versions,
21
+ class_name: superclass.model_name,
22
+ foreign_key: hoardable_source_foreign_key
23
+ )
22
24
 
23
25
  self.table_name = "#{table_name.singularize}#{VERSION_TABLE_SUFFIX}"
24
26
 
@@ -27,7 +29,7 @@ module Hoardable
27
29
  alias_attribute :hoardable_event_uuid, :_event_uuid
28
30
  alias_attribute :hoardable_during, :_during
29
31
 
30
- before_create :assign_temporal_tsrange
32
+ before_create { hoardable_version_service.assign_temporal_tsrange }
31
33
 
32
34
  # @!scope class
33
35
  # @!method trashed
@@ -35,7 +37,7 @@ module Hoardable
35
37
  #
36
38
  # Returns only trashed +versions+ that are currently orphans.
37
39
  scope :trashed, lambda {
38
- left_outer_joins(hoardable_source_key)
40
+ left_outer_joins(:hoardable_source)
39
41
  .where(superclass.table_name => { id: nil })
40
42
  .where(_operation: 'delete')
41
43
  }
@@ -77,7 +79,7 @@ module Hoardable
77
79
 
78
80
  transaction do
79
81
  hoardable_source.tap do |reverted|
80
- reverted.update!(hoardable_source_attributes.without('id'))
82
+ reverted.update!(hoardable_version_service.hoardable_source_attributes.without('id'))
81
83
  reverted.instance_variable_set(:@hoardable_version, self)
82
84
  reverted.run_callbacks(:reverted)
83
85
  end
@@ -90,10 +92,8 @@ module Hoardable
90
92
  raise(Error, 'Version is not trashed, cannot untrash') unless hoardable_operation == 'delete'
91
93
 
92
94
  transaction do
93
- superscope = self.class.superclass.unscoped
94
- superscope.insert(hoardable_source_attributes.merge('id' => hoardable_source_foreign_id))
95
- superscope.find(hoardable_source_foreign_id).tap do |untrashed|
96
- untrashed.send('insert_hoardable_version_on_untrashed')
95
+ hoardable_version_service.insert_untrashed_source.tap do |untrashed|
96
+ untrashed.send('hoardable_source_service').insert_hoardable_version('insert')
97
97
  untrashed.instance_variable_set(:@hoardable_version, self)
98
98
  untrashed.run_callbacks(:untrashed)
99
99
  end
@@ -118,31 +118,67 @@ module Hoardable
118
118
  @hoardable_source_foreign_id ||= public_send(hoardable_source_foreign_key)
119
119
  end
120
120
 
121
- private
122
-
123
121
  delegate :hoardable_source_foreign_key, to: :class
124
122
 
125
- def hoardable_source_attributes
126
- @hoardable_source_attributes ||=
127
- attributes_before_type_cast
128
- .without(hoardable_source_foreign_key)
129
- .reject { |k, _v| k.start_with?('_') }
123
+ def hoardable_version_service
124
+ @hoardable_version_service ||= Service.new(self)
130
125
  end
131
126
 
132
- def previous_temporal_tsrange_end
133
- hoardable_source.versions.only_most_recent.pluck('_during').first&.end
134
- end
127
+ # This is a private service class that manages the construction of {VersionModel} attributes and
128
+ # untrashing / re-insertion into the {SourceModel} table.
129
+ class Service
130
+ attr_reader :version_model
131
+
132
+ def initialize(version_model)
133
+ @version_model = version_model
134
+ end
135
+
136
+ delegate :hoardable_source_foreign_id, :hoardable_source_foreign_key, :hoardable_source, to: :version_model
137
+
138
+ def insert_untrashed_source
139
+ superscope = version_model.class.superclass.unscoped
140
+ superscope.insert(hoardable_source_attributes.merge('id' => hoardable_source_foreign_id))
141
+ superscope.find(hoardable_source_foreign_id)
142
+ end
135
143
 
136
- def assign_temporal_tsrange
137
- range_start = (
138
- previous_temporal_tsrange_end ||
144
+ def hoardable_source_attributes
145
+ @hoardable_source_attributes ||=
146
+ version_model
147
+ .attributes_before_type_cast
148
+ .without(hoardable_source_foreign_key)
149
+ .reject { |k, _v| k.start_with?('_') }
150
+ end
151
+
152
+ def previous_temporal_tsrange_end
153
+ hoardable_source.versions.only_most_recent.pluck('_during').first&.end
154
+ end
155
+
156
+ def hoardable_source_epoch
139
157
  if hoardable_source.class.column_names.include?('created_at')
140
158
  hoardable_source.created_at
141
159
  else
160
+ maybe_warn_about_missing_created_at_column
142
161
  Time.at(0).utc
143
162
  end
144
- )
145
- self._during = (range_start..Time.now.utc)
163
+ end
164
+
165
+ def assign_temporal_tsrange
166
+ version_model._during = ((previous_temporal_tsrange_end || hoardable_source_epoch)..Time.now.utc)
167
+ end
168
+
169
+ def maybe_warn_about_missing_created_at_column
170
+ return unless hoardable_source.class.hoardable_config[:warn_on_missing_created_at_column]
171
+
172
+ source_table_name = hoardable_source.class.table_name
173
+ Hoardable.logger.info(
174
+ <<~LOG
175
+ '#{source_table_name}' does not have a 'created_at' column, so the first version’s temporal period
176
+ will begin at the unix epoch instead. Add a 'created_at' column to '#{source_table_name}'
177
+ or set 'Hoardable.warn_on_missing_created_at_column = false' to disable this message.
178
+ LOG
179
+ )
180
+ end
146
181
  end
182
+ private_constant :Service
147
183
  end
148
184
  end
data/sig/hoardable.rbs CHANGED
@@ -1,14 +1,19 @@
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]
4
+ CONFIG_KEYS: [:enabled, :version_updates, :save_trash, :return_everything, :warn_on_missing_created_at_column]
5
5
  VERSION_CLASS_SUFFIX: String
6
6
  VERSION_TABLE_SUFFIX: String
7
7
  DURING_QUERY: String
8
+ HOARDABLE_CALLBACKS_ENABLED: ^(untyped) -> untyped
9
+ HOARDABLE_SAVE_TRASH: ^(untyped) -> untyped
10
+ HOARDABLE_VERSION_UPDATES: ^(untyped) -> untyped
8
11
  self.@context: Hash[untyped, untyped]
9
12
  self.@config: untyped
13
+ self.@logger: untyped
10
14
 
11
15
  def self.with: (untyped hash) -> untyped
16
+ def self.logger: -> untyped
12
17
 
13
18
  module Tableoid
14
19
  TABLEOID_AREL_CONDITIONS: Proc
@@ -25,57 +30,71 @@ module Hoardable
25
30
 
26
31
  module SourceModel
27
32
  include Tableoid
33
+ @hoardable_source_service: Service
28
34
 
35
+ attr_reader hoardable_version: nil
29
36
  def trashed?: -> untyped
30
37
  def at: (untyped datetime) -> SourceModel
31
38
  def revert_to!: (untyped datetime) -> SourceModel?
32
39
 
33
40
  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
41
+ def hoardable_source_service: -> Service
46
42
 
47
43
  public
48
44
  def version_class: -> untyped
49
- attr_reader hoardable_version: nil
45
+
46
+ class Service
47
+ attr_reader source_model: SourceModel
48
+ def initialize: (SourceModel source_model) -> void
49
+ def insert_hoardable_version: (untyped operation) -> untyped
50
+ def find_or_initialize_hoardable_event_uuid: -> untyped
51
+ def initialize_hoardable_version: (untyped operation) -> untyped
52
+ def initialize_hoardable_data: -> untyped
53
+ def assign_hoardable_context: (:event_uuid | :meta | :note | :whodunit key) -> nil
54
+ def unset_hoardable_version_and_event_uuid: -> nil
55
+ end
50
56
  end
51
57
 
52
58
  module VersionModel
53
- @hoardable_source_attributes: untyped
54
- @hoardable_source_foreign_key: String
55
59
  @hoardable_source_foreign_id: untyped
60
+ @hoardable_source_foreign_key: String
61
+ @hoardable_version_service: Service
56
62
 
57
63
  def revert!: -> untyped
58
64
  def untrash!: -> untyped
59
65
  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
66
  def hoardable_source_foreign_id: -> untyped
66
- def previous_temporal_tsrange_end: -> untyped
67
- def assign_temporal_tsrange: -> Range
67
+ def hoardable_version_service: -> Service
68
+ def hoardable_source_foreign_key: -> String
69
+
70
+ class Service
71
+ @hoardable_source_attributes: untyped
72
+
73
+ attr_reader version_model: VersionModel
74
+ def initialize: (VersionModel version_model) -> void
75
+ def insert_untrashed_source: -> untyped
76
+ def hoardable_source_attributes: -> untyped
77
+ def previous_temporal_tsrange_end: -> untyped
78
+ def hoardable_source_epoch: -> Time
79
+ def assign_temporal_tsrange: -> Range
80
+ def maybe_warn_about_missing_created_at_column: -> nil
81
+ end
68
82
  end
69
83
 
70
84
  module Model
71
85
  include VersionModel
72
86
  include SourceModel
87
+ include Associations
73
88
 
74
89
  attr_reader _hoardable_config: Hash[untyped, untyped]
75
90
  def hoardable_config: (?nil hash) -> untyped
76
91
  def with_hoardable_config: (untyped hash) -> untyped
77
92
  end
78
93
 
94
+ module Associations
95
+ def belongs_to_trashable: (untyped name, ?nil scope, **untyped) -> untyped
96
+ end
97
+
79
98
  class MigrationGenerator
80
99
  @singularized_table_name: untyped
81
100
 
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.5.0
4
+ version: 0.6.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-09-25 00:00:00.000000000 Z
11
+ date: 2022-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord