hoardable 0.8.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1cd77fbd3d35df59423ba95f7286703ae0d3b0f78bd9097b3574c713c38aa4c7
4
- data.tar.gz: d5971e9daf59a9fa5343c13e389b20fc5b6ff193b398d05c958f34dfd056d0cb
3
+ metadata.gz: 5b85dfaf658e447049fcb09281d34dd25188be79f948eda294398f47b19b8244
4
+ data.tar.gz: 67219612736259e2dbc542230cc1490a156a15bc679340176aca35b76aaf516c
5
5
  SHA512:
6
- metadata.gz: 5de03adf485f38e3ee3a24999bf770d92792404894529a5317f9788d15b784c0bcd9aa28b3d2966340a1244296cdc7b4ebe6fdccd6791172b44ca498c4bf5fca
7
- data.tar.gz: a39bd22b66c727ec791e704ec3b24592c068dd2eb29ae0fa7d70a440073bd6d635fd7f24f12d3ba34bf05976b311bab9ec6a5a6fdf9f9069311347d89ae8f8c0
6
+ metadata.gz: cf3c5edfeac5526e7520dc2584caba8bb5399df43acf1ce6bd320b19f44981c154624b9b80c5b415aaeb840fc5d718f1999b4bbaf82eb3ff76149e09621ab0e5
7
+ data.tar.gz: 52112fb9bc55bec2009656cce9571887130333b6460d5478c1a0c113895ccb977ffcc80172954911c6e70d2012f136bf68c64b17bc69ffd7deeaa40a56c97646
data/.rubocop.yml CHANGED
@@ -16,3 +16,6 @@ Metrics/BlockLength:
16
16
 
17
17
  Style/DocumentDynamicEvalDefinition:
18
18
  Enabled: false
19
+
20
+ Naming/PredicateName:
21
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  - Stability is coming.
4
4
 
5
+ ## [0.9.0] - 2022-10-02
6
+
7
+ - **Breaking Change** - `Hoardable.return_everything` was removed in favor of the newly added
8
+ `Hoardable.at`.
9
+
5
10
  ## [0.8.0] - 2022-10-01
6
11
 
7
12
  - **Breaking Change** - Due to the performance benefit of using `insert` for database injection of
data/README.md CHANGED
@@ -31,6 +31,12 @@ gem 'hoardable'
31
31
 
32
32
  And then execute `bundle install`.
33
33
 
34
+ If you would like to generate an initializer with the global [configuration](#configuration) options:
35
+
36
+ ```
37
+ rails g hoardable:initializer
38
+ ```
39
+
34
40
  ### Model Installation
35
41
 
36
42
  You must include `Hoardable::Model` into an ActiveRecord model that you would like to hoard versions
@@ -64,6 +70,9 @@ _Note:_ If you are on Rails 6.1, you might want to set `config.active_record.sch
64
70
  in `application.rb`, so that the enum type is captured in your schema dump. This is not required in
65
71
  Rails 7.
66
72
 
73
+ _Note:_ Creating an inherited table does not copy over the indexes from the parent table. If you
74
+ need to query versions often, you should add appropriate indexes to the `_versions` tables.
75
+
67
76
  ## Usage
68
77
 
69
78
  ### Overview
@@ -99,7 +108,7 @@ Each `PostVersion` has access to the same attributes, relationships, and other m
99
108
 
100
109
  If you ever need to revert to a specific version, you can call `version.revert!` on it.
101
110
 
102
- ``` ruby
111
+ ```ruby
103
112
  post = Post.create!(title: "Title")
104
113
  post.update!(title: "Whoops")
105
114
  post.reload.versions.last.revert!
@@ -107,7 +116,7 @@ post.title # => "Title"
107
116
  ```
108
117
 
109
118
  If you would like to untrash a specific version, you can call `version.untrash!` on it. This will
110
- re-insert the model in the parent class’s table with it’s original primary key.
119
+ re-insert the model in the parent class’s table with the original primary key.
111
120
 
112
121
  ```ruby
113
122
  post = Post.create!(title: "Title")
@@ -139,16 +148,15 @@ PostVersion.at(1.day.ago).find_by(hoardable_source_id: post.id) # => #<PostVersi
139
148
 
140
149
  The source model class also has an `.at` method:
141
150
 
142
- ``` ruby
151
+ ```ruby
143
152
  Post.at(1.day.ago) # => [#<Post>, #<Post>]
144
153
  ```
145
154
 
146
- This will return an ActiveRecord scoped query of all `Posts` and `PostVersions` that were valid at
147
- that time, all cast as instances of `Post`.
155
+ This will return an ActiveRecord scoped query of all `Post` and `PostVersion` records that were
156
+ valid at that time, all cast as instances of `Post`.
148
157
 
149
- _Note:_ A `Version` is not created upon initial parent model creation. To accurately track the
150
- beginning of the first temporal period, you will need to ensure the source model table has a
151
- `created_at` timestamp column.
158
+ There is also an `at` method on `Hoardable` itself for more complex temporal resource querying. See
159
+ [Relationships](#relationships) for more.
152
160
 
153
161
  By default, `hoardable` will keep copies of records you have destroyed. You can query them
154
162
  specifically with:
@@ -156,10 +164,12 @@ specifically with:
156
164
  ```ruby
157
165
  PostVersion.trashed
158
166
  Post.version_class.trashed # <- same thing as above
167
+ PostVersion.trashed.first.trashed? # <- true
159
168
  ```
160
169
 
161
- _Note:_ Creating an inherited table does not copy over the indexes from the parent table. If you
162
- need to query versions often, you should add appropriate indexes to the `_versions` tables.
170
+ _Note:_ A `Version` is not created upon initial parent model creation. To accurately track the
171
+ beginning of the first temporal period, you will need to ensure the source model table has a
172
+ `created_at` timestamp column.
163
173
 
164
174
  ### Tracking Contextual Data
165
175
 
@@ -263,7 +273,6 @@ The configurable options are:
263
273
  Hoardable.enabled # => default true
264
274
  Hoardable.version_updates # => default true
265
275
  Hoardable.save_trash # => default true
266
- Hoardable.return_everything # => default false
267
276
  ```
268
277
 
269
278
  `Hoardable.enabled` controls whether versions will be ever be created.
@@ -273,10 +282,6 @@ Hoardable.return_everything # => default false
273
282
  `Hoardable.save_trash` controls whether to create versions upon record deletion. When this is set to
274
283
  `false`, all versions of a record will be deleted when the record is destroyed.
275
284
 
276
- `Hoardable.return_everything` controls whether to include versions when doing queries for source
277
- models. This is typically only useful to set around a block, as explained below in
278
- [Relationships](#relationships).
279
-
280
285
  If you would like to temporarily set a config setting, you can use `Hoardable.with`:
281
286
 
282
287
  ```ruby
@@ -323,8 +328,54 @@ class Comment
323
328
  end
324
329
  ```
325
330
 
326
- Sometimes youll trash something that `has_many :children, dependent: :destroy` and both the parent
327
- and child model classes include `Hoardable::Model`. Whenever a hoardable version is created in a
331
+ Sometimes you'll have a Hoardable record that `has_many` other Hoardable records and you will want
332
+ to know the state of both the parent record and the children at a cetain point in time. You
333
+ accomplish this by establishing a `has_many_hoardable` relationship and using the `Hoardable.at`
334
+ method:
335
+
336
+ ```ruby
337
+ class Post
338
+ include Hoardable::Model
339
+ has_many_hoardable :comments
340
+ end
341
+
342
+ def Comment
343
+ include Hoardable::Model
344
+ end
345
+
346
+ post = Post.create!(title: 'Title')
347
+ comment1 = post.comments.create!(body: 'Comment')
348
+ comment2 = post.comments.create!(body: 'Comment')
349
+ datetime = DateTime.current
350
+ comment2.destroy!
351
+ post.update!(title: 'New Title')
352
+ post_id = post.id # 1
353
+
354
+ Hoardable.at(datetime) do
355
+ post = Post.hoardable.find(post_id)
356
+ post.title # => 'Title'
357
+ post.comments.size # => 2
358
+ post.id # => 2
359
+ post.version? # => true
360
+ post.hoardable_source_id # => 1
361
+ end
362
+ ```
363
+
364
+ There are some additional details to point out above. Firstly, it is important to note that the
365
+ final `post.id` yields a different value than the originally created `Post`. This is because the
366
+ `post` within the `#at` block is actually a temporal version, since it has been subsequently
367
+ updated, but it has been reified as a `Post` for the purposes of your business logic (serialization,
368
+ rendering views, exporting, etc). Don’t fret - you will not be able to commit any updates to the
369
+ version, even though it is masquerading as a `Post`.
370
+
371
+ If you are ever unsure if a Hoardable record is a "source" or a "version", you can be sure by
372
+ calling `version?` on it. If you want to get the true original source record ID, you can call
373
+ `hoardable_source_id`. Finally, if you prepend `.hoardable` to a `.find` call on the source model
374
+ class, you can always find the relevant source or temporal version record using just the original
375
+ source record’s id.
376
+
377
+ Sometimes you’ll trash something that `has_many_hoardable :children, dependent: :destroy` and want
378
+ to untrash everything in a similar dependent manner. Whenever a hoardable version is created in a
328
379
  database transaction, it will create or re-use a unique event UUID for that transaction and tag all
329
380
  versions created with it. That way, when you `untrash!` a record, you can find and `untrash!`
330
381
  records that were trashed with it:
@@ -332,7 +383,7 @@ records that were trashed with it:
332
383
  ```ruby
333
384
  class Post < ActiveRecord::Base
334
385
  include Hoardable::Model
335
- has_many :comments, dependent: :destroy # `Comment` also includes `Hoardable::Model`
386
+ has_many_hoardable :comments, dependent: :destroy # `Comment` also includes `Hoardable::Model`
336
387
 
337
388
  after_untrashed do
338
389
  Comment
@@ -344,22 +395,6 @@ class Post < ActiveRecord::Base
344
395
  end
345
396
  ```
346
397
 
347
- If there are models that might be related to versions that are trashed or otherwise, and/or might be
348
- trashed themselves, you can bypass the inherited tables query handling altogether by using the
349
- `return_everything` configuration variable in `Hoardable.with`. This will ensure that you always see
350
- all records, including update and trashed versions.
351
-
352
- ```ruby
353
- post.destroy!
354
-
355
- Hoardable.with(return_everything: true) do
356
- post = Post.find(post.id) # returns the trashed post as if it was not
357
- post.comments # returns the trashed comments as well
358
- end
359
-
360
- post.reload # raises ActiveRecord::RecordNotFound
361
- ```
362
-
363
398
  ## Gem Comparison
364
399
 
365
400
  ### [`paper_trail`](https://github.com/paper-trail-gem/paper_trail)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ module Hoardable
6
+ # Generates an initializer file for {Hoardable} configuration.
7
+ class InitializerGenerator < Rails::Generators::Base
8
+ def create_initializer_file
9
+ create_file(
10
+ 'config/initializers/hoardable.rb',
11
+ <<~TEXT
12
+ # Hoardable configuration defaults are below. Learn more at https://github.com/waymondo/hoardable#configuration
13
+ #
14
+ # Hoardable.enabled = true
15
+ # Hoardable.version_updates = true
16
+ # Hoardable.save_trash = true
17
+ TEXT
18
+ )
19
+ end
20
+ end
21
+ end
@@ -10,6 +10,20 @@ class Create<%= class_name.singularize %>Versions < ActiveRecord::Migration[<%=
10
10
  t.enum :_operation, enum_type: 'hoardable_operation', null: false, index: true
11
11
  t.<%= foreign_key_type %> :hoardable_source_id, null: false, index: true
12
12
  end
13
+ execute(
14
+ <<~SQL
15
+ CREATE OR REPLACE FUNCTION hoardable_version_prevent_update() RETURNS trigger
16
+ LANGUAGE plpgsql AS
17
+ $$BEGIN
18
+ RAISE EXCEPTION 'updating a version is not allowed';
19
+ RETURN NEW;
20
+ END;$$;
21
+
22
+ CREATE TRIGGER <%= singularized_table_name %>_versions_prevent_update
23
+ BEFORE UPDATE ON <%= singularized_table_name %>_versions FOR EACH ROW
24
+ EXECUTE PROCEDURE hoardable_version_prevent_update();
25
+ SQL
26
+ )
13
27
  add_index(:<%= singularized_table_name %>_versions, :id, unique: true)
14
28
  add_index(
15
29
  :<%= singularized_table_name %>_versions,
@@ -25,6 +25,20 @@ class Create<%= class_name.singularize %>Versions < ActiveRecord::Migration[<%=
25
25
  t.column :_operation, :hoardable_operation, null: false, index: true
26
26
  t.<%= foreign_key_type %> :hoardable_source_id, null: false, index: true
27
27
  end
28
+ execute(
29
+ <<~SQL
30
+ CREATE OR REPLACE FUNCTION hoardable_version_prevent_update() RETURNS trigger
31
+ LANGUAGE plpgsql AS
32
+ $$BEGIN
33
+ RAISE EXCEPTION 'updating a version is not allowed';
34
+ RETURN NEW;
35
+ END;$$;
36
+
37
+ CREATE TRIGGER <%= singularized_table_name %>_versions_prevent_update
38
+ BEFORE UPDATE ON <%= singularized_table_name %>_versions FOR EACH ROW
39
+ EXECUTE PROCEDURE hoardable_version_prevent_update();
40
+ SQL
41
+ )
28
42
  add_index(:<%= singularized_table_name %>_versions, :id, unique: true)
29
43
  add_index(
30
44
  :<%= singularized_table_name %>_versions,
@@ -7,6 +7,26 @@ module Hoardable
7
7
  module Associations
8
8
  extend ActiveSupport::Concern
9
9
 
10
+ # An +ActiveRecord+ extension that allows looking up {VersionModel}s by +hoardable_source_id+ as
11
+ # if they were {SourceModel}s.
12
+ module HasManyScope
13
+ def scope
14
+ @scope ||= hoardable_scope
15
+ end
16
+
17
+ private
18
+
19
+ def hoardable_scope
20
+ if Hoardable.instance_variable_get('@at') &&
21
+ (hoardable_source_id = @association.owner.hoardable_source_id)
22
+ @association.scope.rewhere(@association.reflection.foreign_key => hoardable_source_id)
23
+ else
24
+ @association.scope
25
+ end
26
+ end
27
+ end
28
+ private_constant :HasManyScope
29
+
10
30
  class_methods do
11
31
  # A wrapper for +ActiveRecord+’s +belongs_to+ that allows for falling back to the most recent
12
32
  # trashed +version+, in the case that the related source has been trashed.
@@ -29,6 +49,12 @@ module Hoardable
29
49
  end
30
50
  RUBY
31
51
  end
52
+
53
+ # A wrapper for +ActiveRecord+’s +has_many+ that allows for finding temporal versions of a
54
+ # record cast as instances of the {SourceModel}, when doing a {Hoardable#at} query.
55
+ def has_many_hoardable(name, scope = nil, **options)
56
+ has_many(name, scope, **options) { include HasManyScope }
57
+ end
32
58
  end
33
59
  end
34
60
  end
@@ -23,6 +23,15 @@ module Hoardable
23
23
  Thread.current[:hoardable_event_uuid] ||= ActiveRecord::Base.connection.query('SELECT gen_random_uuid();')[0][0]
24
24
  end
25
25
 
26
+ def hoardable_version_source_id
27
+ @hoardable_version_source_id ||= query_hoardable_version_source_id
28
+ end
29
+
30
+ def query_hoardable_version_source_id
31
+ primary_key = source_record.class.primary_key
32
+ version_class.where(primary_key => source_record.read_attribute(primary_key)).pluck('hoardable_source_id')[0]
33
+ end
34
+
26
35
  def initialize_version_attributes(operation)
27
36
  source_record.attributes_before_type_cast.without('id').merge(
28
37
  source_record.changes.transform_values { |h| h[0] },
@@ -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 warn_on_missing_created_at_column].freeze
11
+ CONFIG_KEYS = %i[enabled version_updates save_trash warn_on_missing_created_at_column].freeze
12
12
 
13
13
  VERSION_CLASS_SUFFIX = 'Version'
14
14
  private_constant :VERSION_CLASS_SUFFIX
@@ -36,7 +36,7 @@ module Hoardable
36
36
 
37
37
  @context = {}
38
38
  @config = CONFIG_KEYS.to_h do |key|
39
- [key, key != :return_everything]
39
+ [key, true]
40
40
  end
41
41
 
42
42
  class << self
@@ -75,6 +75,17 @@ module Hoardable
75
75
  @context = current_context
76
76
  end
77
77
 
78
+ # Allows performing a query for record states at a certain time. Returned {SourceModel}
79
+ # instances within the block may be {SourceModel} or {VersionModel} records.
80
+ #
81
+ # @param datetime [DateTime, Time] the datetime or time to temporally query records at
82
+ def at(datetime)
83
+ @at = datetime
84
+ yield
85
+ ensure
86
+ @at = nil
87
+ end
88
+
78
89
  # @!visibility private
79
90
  def logger
80
91
  @logger ||= ActiveSupport::TaggedLogging.new(Logger.new($stdout))
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hoardable
4
- # This concern provides support for PostgreSQL’s tableoid system column to {SourceModel}.
5
- module Tableoid
4
+ # This concern provides support for PostgreSQL’s tableoid system column to {SourceModel} and
5
+ # temporal +ActiveRecord+ scopes.
6
+ module Scopes
6
7
  extend ActiveSupport::Concern
7
8
 
8
9
  TABLEOID_AREL_CONDITIONS = lambda do |arel_table, condition|
@@ -19,10 +20,10 @@ module Hoardable
19
20
 
20
21
  # By default {Hoardable} only returns instances of the parent table, and not the +versions+ in
21
22
  # 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
+ # the code in a `Hoardable.at(datetime)` block.
23
24
  default_scope do
24
- if hoardable_config[:return_everything]
25
- where(nil)
25
+ if (hoardable_at = Hoardable.instance_variable_get('@at'))
26
+ at(hoardable_at)
26
27
  else
27
28
  exclude_versions
28
29
  end
@@ -51,6 +52,18 @@ module Hoardable
51
52
  # Excludes +versions+ of the parent +ActiveRecord+ class. This is included by default in the
52
53
  # source model’s +default_scope+.
53
54
  scope :exclude_versions, -> { where(TABLEOID_AREL_CONDITIONS.call(arel_table, :eq)) }
55
+
56
+ # @!scope class
57
+ # @!method at
58
+ # @return [ActiveRecord<Object>]
59
+ #
60
+ # Returns instances of the source model and versions that were valid at the supplied
61
+ # +datetime+ or +time+, all cast as instances of the source model.
62
+ scope :at, lambda { |datetime|
63
+ include_versions.where(id: version_class.at(datetime).select('id')).or(
64
+ where.not(id: version_class.select(:hoardable_source_id).where(DURING_QUERY, datetime))
65
+ )
66
+ }
54
67
  end
55
68
 
56
69
  private
@@ -16,15 +16,30 @@ module Hoardable
16
16
  # @return [String] The database operation that created the +version+ - either +update+ or +delete+.
17
17
  delegate :hoardable_event_uuid, :hoardable_operation, to: :hoardable_version, allow_nil: true
18
18
 
19
+ # A module for overriding +ActiveRecord#find_one+’ in the case you are doing a temporal query
20
+ # and the current {SourceModel} record may in fact be a {VersionModel} record.
21
+ module FinderMethods
22
+ def find_one(id)
23
+ conditions = { primary_key => [id, *version_class.where(hoardable_source_id: id).select(primary_key).ids] }
24
+ find_by(conditions) || where(conditions).raise_record_not_found_exception!
25
+ end
26
+ end
27
+ private_constant :FinderMethods
28
+
19
29
  class_methods do
20
30
  # The dynamically generated +Version+ class for this model.
21
31
  def version_class
22
32
  "#{name}#{VERSION_CLASS_SUFFIX}".constantize
23
33
  end
34
+
35
+ # Extends the current {SourceModel} scoping to include Hoardable’s {FinderMethods} overrides.
36
+ def hoardable
37
+ extending(FinderMethods)
38
+ end
24
39
  end
25
40
 
26
41
  included do
27
- include Tableoid
42
+ include Scopes
28
43
 
29
44
  around_update(if: [HOARDABLE_CALLBACKS_ENABLED, HOARDABLE_VERSION_UPDATES]) do |_, block|
30
45
  hoardable_client.insert_hoardable_version('update', &block)
@@ -48,25 +63,22 @@ module Hoardable
48
63
  inverse_of: :hoardable_source,
49
64
  foreign_key: :hoardable_source_id
50
65
  )
51
-
52
- # @!scope class
53
- # @!method at
54
- # @return [ActiveRecord<Object>]
55
- #
56
- # Returns instances of the source model and versions that were valid at the supplied
57
- # +datetime+ or +time+, all cast as instances of the source model.
58
- scope :at, lambda { |datetime|
59
- include_versions.where(id: version_class.at(datetime).select('id')).or(
60
- where.not(id: version_class.select(:hoardable_source_id).where(DURING_QUERY, datetime))
61
- )
62
- }
63
66
  end
64
67
 
65
- # Returns a boolean of whether the record is actually a trashed +version+.
68
+ # Returns a boolean of whether the record is actually a trashed +version+ cast as an instance of the
69
+ # source model.
66
70
  #
67
71
  # @return [Boolean]
68
72
  def trashed?
69
- versions.trashed.only_most_recent.first&.hoardable_source_foreign_id == id
73
+ versions.trashed.only_most_recent.first&.hoardable_source_id == id
74
+ end
75
+
76
+ # Returns a boolean of whether the record is actually a +version+ cast as an instance of the
77
+ # source model.
78
+ #
79
+ # @return [Boolean]
80
+ def version?
81
+ !!hoardable_client.hoardable_version_source_id
70
82
  end
71
83
 
72
84
  # Returns the +version+ at the supplied +datetime+ or +time+. It will return +self+ if there is
@@ -89,6 +101,15 @@ module Hoardable
89
101
  version.is_a?(version_class) ? version.revert! : self
90
102
  end
91
103
 
104
+ # Returns the +hoardable_source_id+ that represents the original {SourceModel} record’s ID. Will
105
+ # return nil if the current {SourceModel} record is not an instance of a {VersionModel} cast as
106
+ # {SourceModel}.
107
+ #
108
+ # @return [Integer, nil]
109
+ def hoardable_source_id
110
+ hoardable_client.hoardable_version_source_id || id
111
+ end
112
+
92
113
  delegate :version_class, to: :class
93
114
 
94
115
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hoardable
4
- VERSION = '0.8.0'
4
+ VERSION = '0.9.1'
5
5
  end
@@ -113,17 +113,17 @@ module Hoardable
113
113
  _data&.dig('changes')
114
114
  end
115
115
 
116
- # Returns the foreign reference that represents the source model of the version.
117
- def hoardable_source_foreign_id
118
- @hoardable_source_foreign_id ||= public_send(:hoardable_source_id)
116
+ # Returns the ID of the {SourceModel} that created this {VersionModel}
117
+ def hoardable_source_id
118
+ read_attribute('hoardable_source_id')
119
119
  end
120
120
 
121
121
  private
122
122
 
123
123
  def insert_untrashed_source
124
124
  superscope = self.class.superclass.unscoped
125
- superscope.insert(hoardable_source_attributes.merge('id' => hoardable_source_foreign_id))
126
- superscope.find(hoardable_source_foreign_id)
125
+ superscope.insert(hoardable_source_attributes.merge('id' => hoardable_source_id))
126
+ superscope.find(hoardable_source_id)
127
127
  end
128
128
 
129
129
  def hoardable_source_attributes
data/lib/hoardable.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative 'hoardable/version'
4
4
  require_relative 'hoardable/hoardable'
5
- require_relative 'hoardable/tableoid'
5
+ require_relative 'hoardable/scopes'
6
6
  require_relative 'hoardable/error'
7
7
  require_relative 'hoardable/database_client'
8
8
  require_relative 'hoardable/source_model'
@@ -10,3 +10,4 @@ require_relative 'hoardable/version_model'
10
10
  require_relative 'hoardable/model'
11
11
  require_relative 'hoardable/associations'
12
12
  require_relative 'generators/hoardable/migration_generator'
13
+ require_relative 'generators/hoardable/initializer_generator'
data/sig/hoardable.rbs CHANGED
@@ -1,7 +1,7 @@
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, :warn_on_missing_created_at_column]
4
+ CONFIG_KEYS: [:enabled, :version_updates, :save_trash, :warn_on_missing_created_at_column]
5
5
  VERSION_CLASS_SUFFIX: String
6
6
  VERSION_TABLE_SUFFIX: String
7
7
  DURING_QUERY: String
@@ -10,12 +10,14 @@ module Hoardable
10
10
  HOARDABLE_VERSION_UPDATES: ^(untyped) -> untyped
11
11
  self.@context: Hash[untyped, untyped]
12
12
  self.@config: untyped
13
+ self.@at: nil
13
14
  self.@logger: untyped
14
15
 
15
16
  def self.with: (untyped hash) -> untyped
17
+ def self.at: (untyped datetime) -> untyped
16
18
  def self.logger: -> untyped
17
19
 
18
- module Tableoid
20
+ module Scopes
19
21
  TABLEOID_AREL_CONDITIONS: Proc
20
22
 
21
23
  private
@@ -29,10 +31,14 @@ module Hoardable
29
31
  end
30
32
 
31
33
  class DatabaseClient
32
- attr_reader source_model: SourceModel
33
- def initialize: (SourceModel source_model) -> void
34
+ @hoardable_version_source_id: untyped
35
+
36
+ attr_reader source_record: SourceModel
37
+ def initialize: (SourceModel source_record) -> void
34
38
  def insert_hoardable_version: (untyped operation) -> untyped
35
39
  def find_or_initialize_hoardable_event_uuid: -> untyped
40
+ def hoardable_version_source_id: -> untyped
41
+ def query_hoardable_version_source_id: -> untyped
36
42
  def initialize_version_attributes: (untyped operation) -> untyped
37
43
  def initialize_temporal_range: -> Range
38
44
  def initialize_hoardable_data: -> untyped
@@ -44,29 +50,35 @@ module Hoardable
44
50
  end
45
51
 
46
52
  module SourceModel
47
- include Tableoid
53
+ include Scopes
48
54
  @hoardable_client: DatabaseClient
49
55
 
50
56
  attr_reader hoardable_version: untyped
51
57
  def trashed?: -> untyped
58
+ def version?: -> untyped
52
59
  def at: (untyped datetime) -> SourceModel
53
60
  def revert_to!: (untyped datetime) -> SourceModel?
61
+ def hoardable_source_id: -> untyped
54
62
 
55
63
  private
56
64
  def hoardable_client: -> DatabaseClient
57
65
 
58
66
  public
59
67
  def version_class: -> untyped
68
+ def hoardable: -> untyped
69
+
70
+ module FinderMethods
71
+ def find_one: (untyped id) -> untyped
72
+ end
60
73
  end
61
74
 
62
75
  module VersionModel
63
- @hoardable_source_foreign_id: untyped
64
76
  @hoardable_source_attributes: untyped
65
77
 
66
78
  def revert!: -> untyped
67
79
  def untrash!: -> untyped
68
80
  def changes: -> untyped
69
- def hoardable_source_foreign_id: -> untyped
81
+ def hoardable_source_id: -> untyped
70
82
 
71
83
  private
72
84
  def insert_untrashed_source: -> untyped
@@ -88,6 +100,17 @@ module Hoardable
88
100
 
89
101
  module Associations
90
102
  def belongs_to_trashable: (untyped name, ?nil scope, **untyped) -> untyped
103
+ def has_many_hoardable: (untyped name, ?nil scope, **untyped) -> untyped
104
+
105
+ module HasManyScope
106
+ @scope: untyped
107
+ @association: bot
108
+
109
+ def scope: -> untyped
110
+
111
+ private
112
+ def hoardable_scope: -> untyped
113
+ end
91
114
  end
92
115
 
93
116
  class MigrationGenerator
@@ -98,4 +121,8 @@ module Hoardable
98
121
  def migration_template_name: -> String
99
122
  def singularized_table_name: -> untyped
100
123
  end
124
+
125
+ class InitializerGenerator
126
+ def create_initializer_file: -> untyped
127
+ end
101
128
  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.8.0
4
+ version: 0.9.1
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-10-01 00:00:00.000000000 Z
11
+ date: 2022-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -104,6 +104,7 @@ files:
104
104
  - LICENSE.txt
105
105
  - README.md
106
106
  - Rakefile
107
+ - lib/generators/hoardable/initializer_generator.rb
107
108
  - lib/generators/hoardable/migration_generator.rb
108
109
  - lib/generators/hoardable/templates/migration.rb.erb
109
110
  - lib/generators/hoardable/templates/migration_6.rb.erb
@@ -113,8 +114,8 @@ files:
113
114
  - lib/hoardable/error.rb
114
115
  - lib/hoardable/hoardable.rb
115
116
  - lib/hoardable/model.rb
117
+ - lib/hoardable/scopes.rb
116
118
  - lib/hoardable/source_model.rb
117
- - lib/hoardable/tableoid.rb
118
119
  - lib/hoardable/version.rb
119
120
  - lib/hoardable/version_model.rb
120
121
  - sig/hoardable.rbs