hoardable 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +4 -0
 - data/Gemfile +1 -1
 - data/README.md +107 -111
 - data/lib/generators/hoardable/migration_generator.rb +6 -0
 - data/lib/hoardable/arel_visitors.rb +9 -3
 - data/lib/hoardable/has_one.rb +3 -3
 - data/lib/hoardable/schema_statements.rb +1 -1
 - data/lib/hoardable/version.rb +1 -1
 - metadata +3 -21
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 8c41a6c69f62f7e2a99fefe00229a7244f5cd0dcb9ed3b0d243db9adf9cabd98
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 30dc9d7a551c29331a7736f7b825c0b5f9db83bf5c5cd537d5d2910908f683ff
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ad46ae05e3241052089aaf432016b906f648051fae6405e2ce4a90c7f247942a09a011d2fc35e6558695814949ef37a0398d36baaa71500f2c31d33436a7eac7
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: b3307392cdff1b14a37192cd1a004099c5d99d7dd0ce3d0f8fe230c1dac4b59697c4708f5859cb7b2b831f45f1a3a6489cdce2eaf464fef2d9e135bd902e4f26
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Hoardable 
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            Hoardable is an ActiveRecord extension for Ruby 3+, Rails 7+, and PostgreSQL that allows for
         
     | 
| 
      
 3 
     | 
    
         
            +
            Hoardable is an ActiveRecord extension for Ruby 3+, Rails 7+, and PostgreSQL 9+ that allows for
         
     | 
| 
       4 
4 
     | 
    
         
             
            versioning and soft-deletion of records through the use of _uni-temporal inherited tables_.
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            [Temporal tables](https://en.wikipedia.org/wiki/Temporal_database) are a database design pattern
         
     | 
| 
         @@ -9,15 +9,13 @@ each database row has a time range that represents the row’s valid time range 
     | 
|
| 
       9 
9 
     | 
    
         
             
            "uni-temporal".
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
            [Table inheritance](https://www.postgresql.org/docs/current/ddl-inherit.html) is a feature of
         
     | 
| 
       12 
     | 
    
         
            -
            PostgreSQL that allows  
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
            PostgreSQL that allows one table to inherit all columns from a parent. The descendant table’s schema
         
     | 
| 
      
 13 
     | 
    
         
            +
            will stay in sync with its parent; if a new column is added to or removed from the parent, the
         
     | 
| 
      
 14 
     | 
    
         
            +
            schema change is reflected on its descendants.
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
            With these concepts combined, `hoardable` offers a model versioning and soft deletion system for
         
     | 
| 
       17 
17 
     | 
    
         
             
            Rails. Versions of records are stored in separate, inherited tables along with their valid time
         
     | 
| 
       18 
     | 
    
         
            -
            ranges and contextual data. 
     | 
| 
       19 
     | 
    
         
            -
            be more explicit and obvious on the lower database level, while still familiar and convenient to use
         
     | 
| 
       20 
     | 
    
         
            -
            within Ruby on Rails.
         
     | 
| 
      
 18 
     | 
    
         
            +
            ranges and contextual data.
         
     | 
| 
       21 
19 
     | 
    
         | 
| 
       22 
20 
     | 
    
         
             
            [👉 Documentation](https://www.rubydoc.info/gems/hoardable)
         
     | 
| 
       23 
21 
     | 
    
         | 
| 
         @@ -26,7 +24,7 @@ within Ruby on Rails. 
     | 
|
| 
       26 
24 
     | 
    
         
             
            Add this line to your application's Gemfile:
         
     | 
| 
       27 
25 
     | 
    
         | 
| 
       28 
26 
     | 
    
         
             
            ```ruby
         
     | 
| 
       29 
     | 
    
         
            -
            gem  
     | 
| 
      
 27 
     | 
    
         
            +
            gem "hoardable"
         
     | 
| 
       30 
28 
     | 
    
         
             
            ```
         
     | 
| 
       31 
29 
     | 
    
         | 
| 
       32 
30 
     | 
    
         
             
            Run `bundle install`, and then run:
         
     | 
| 
         @@ -36,10 +34,9 @@ bin/rails g hoardable:install 
     | 
|
| 
       36 
34 
     | 
    
         
             
            bin/rails db:migrate
         
     | 
| 
       37 
35 
     | 
    
         
             
            ```
         
     | 
| 
       38 
36 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
            ### Model  
     | 
| 
      
 37 
     | 
    
         
            +
            ### Model installation
         
     | 
| 
       40 
38 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
            of:
         
     | 
| 
      
 39 
     | 
    
         
            +
            Include `Hoardable::Model` into an ActiveRecord model you would like to hoard versions of:
         
     | 
| 
       43 
40 
     | 
    
         | 
| 
       44 
41 
     | 
    
         
             
            ```ruby
         
     | 
| 
       45 
42 
     | 
    
         
             
            class Post < ActiveRecord::Base
         
     | 
| 
         @@ -48,24 +45,15 @@ class Post < ActiveRecord::Base 
     | 
|
| 
       48 
45 
     | 
    
         
             
            end
         
     | 
| 
       49 
46 
     | 
    
         
             
            ```
         
     | 
| 
       50 
47 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
            Run the generator command to create a database migration and migrate it:
         
     | 
| 
       52 
49 
     | 
    
         | 
| 
       53 
50 
     | 
    
         
             
            ```
         
     | 
| 
       54 
51 
     | 
    
         
             
            bin/rails g hoardable:migration Post
         
     | 
| 
       55 
52 
     | 
    
         
             
            bin/rails db:migrate
         
     | 
| 
       56 
53 
     | 
    
         
             
            ```
         
     | 
| 
       57 
54 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
            By default, it will guess the foreign key type for the `_versions` table based on the primary key of
         
     | 
| 
       59 
     | 
    
         
            -
            the model specified in the migration generator above. If you want/need to specify this explicitly,
         
     | 
| 
       60 
     | 
    
         
            -
            you can do so:
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
            ```
         
     | 
| 
       63 
     | 
    
         
            -
            bin/rails g hoardable:migration Post --foreign-key-type uuid
         
     | 
| 
       64 
     | 
    
         
            -
            ```
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
55 
     | 
    
         
             
            _*Note*:_ Creating an inherited table does not inherit the indexes from the parent table. If you
         
     | 
| 
       67 
     | 
    
         
            -
            need to query versions often, you should add appropriate indexes to the `_versions` tables. 
     | 
| 
       68 
     | 
    
         
            -
            [here](https://github.com/waymondo/hoardable/issues/30) for more info.
         
     | 
| 
      
 56 
     | 
    
         
            +
            need to query versions often, you should add appropriate indexes to the `_versions` tables.
         
     | 
| 
       69 
57 
     | 
    
         | 
| 
       70 
58 
     | 
    
         
             
            ## Usage
         
     | 
| 
       71 
59 
     | 
    
         | 
| 
         @@ -119,33 +107,48 @@ original primary key. 
     | 
|
| 
       119 
107 
     | 
    
         | 
| 
       120 
108 
     | 
    
         
             
            ```ruby
         
     | 
| 
       121 
109 
     | 
    
         
             
            post = Post.create!(title: "Title")
         
     | 
| 
       122 
     | 
    
         
            -
            post.id # => 1
         
     | 
| 
       123 
110 
     | 
    
         
             
            post.destroy!
         
     | 
| 
       124 
111 
     | 
    
         
             
            post.versions.size # => 1
         
     | 
| 
       125 
112 
     | 
    
         
             
            Post.find(post.id) # raises ActiveRecord::RecordNotFound
         
     | 
| 
       126 
113 
     | 
    
         
             
            trashed_post = post.versions.trashed.last
         
     | 
| 
       127 
     | 
    
         
            -
            trashed_post.id # => 2
         
     | 
| 
       128 
114 
     | 
    
         
             
            trashed_post.untrash!
         
     | 
| 
       129 
115 
     | 
    
         
             
            Post.find(post.id) # #<Post>
         
     | 
| 
       130 
116 
     | 
    
         
             
            ```
         
     | 
| 
       131 
117 
     | 
    
         | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
            represents the primary key value of the original source record.
         
     | 
| 
      
 118 
     | 
    
         
            +
            Source and version records pull from the same ID sequence. This allows for uniquely identifying
         
     | 
| 
      
 119 
     | 
    
         
            +
            records from each other. Both source record and version have an automatically managed `hoardable_id`
         
     | 
| 
      
 120 
     | 
    
         
            +
            attribute that always represents the primary key value of the original source record:
         
     | 
| 
       136 
121 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
      
 122 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 123 
     | 
    
         
            +
            post = Post.create!(title: "Title")
         
     | 
| 
      
 124 
     | 
    
         
            +
            post.id # => 1
         
     | 
| 
      
 125 
     | 
    
         
            +
            post.hoardable_id # => 1
         
     | 
| 
      
 126 
     | 
    
         
            +
            post.version? # => false
         
     | 
| 
      
 127 
     | 
    
         
            +
            post.update!(title: "New Title")
         
     | 
| 
      
 128 
     | 
    
         
            +
            version = post.reload.versions.last
         
     | 
| 
      
 129 
     | 
    
         
            +
            version.id # => 2
         
     | 
| 
      
 130 
     | 
    
         
            +
            version.hoardable_id # => 1
         
     | 
| 
      
 131 
     | 
    
         
            +
            version.version? # => true
         
     | 
| 
      
 132 
     | 
    
         
            +
            ```
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            ### Querying and temporal lookup
         
     | 
| 
       138 
135 
     | 
    
         | 
| 
       139 
     | 
    
         
            -
            Including `Hoardable::Model` into your source model modifies  
     | 
| 
       140 
     | 
    
         
            -
            query the parent table:
         
     | 
| 
      
 136 
     | 
    
         
            +
            Including `Hoardable::Model` into your source model modifies `default_scope` to make sure you only
         
     | 
| 
      
 137 
     | 
    
         
            +
            ever query the parent table and not the inherited ones:
         
     | 
| 
       141 
138 
     | 
    
         | 
| 
       142 
139 
     | 
    
         
             
            ```ruby
         
     | 
| 
       143 
140 
     | 
    
         
             
            Post.where(state: :draft).to_sql # => SELECT posts.* FROM ONLY posts WHERE posts.status = 'draft'
         
     | 
| 
       144 
141 
     | 
    
         
             
            ```
         
     | 
| 
       145 
142 
     | 
    
         | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
      
 143 
     | 
    
         
            +
            Note the `FROM ONLY` above. If you are executing raw SQL, you will need to include the `ONLY`
         
     | 
| 
      
 144 
     | 
    
         
            +
            keyword if you do not wish to return versions in your results. This includes `JOIN`-ing on this
         
     | 
| 
      
 145 
     | 
    
         
            +
            table as well.
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 148 
     | 
    
         
            +
            User.joins(:posts).to_sql # => SELECT users.* FROM users INNER JOIN ONLY posts ON posts.user_id = users.id
         
     | 
| 
      
 149 
     | 
    
         
            +
            ```
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
            Learn more about table inheritance in [the PostgreSQL documentation](https://www.postgresql.org/docs/current/ddl-inherit.html).
         
     | 
| 
       149 
152 
     | 
    
         | 
| 
       150 
153 
     | 
    
         
             
            Since a `PostVersion` is an `ActiveRecord` class, you can query them like another model resource:
         
     | 
| 
       151 
154 
     | 
    
         | 
| 
         @@ -153,6 +156,14 @@ Since a `PostVersion` is an `ActiveRecord` class, you can query them like anothe 
     | 
|
| 
       153 
156 
     | 
    
         
             
            post.versions.where(state: :draft)
         
     | 
| 
       154 
157 
     | 
    
         
             
            ```
         
     | 
| 
       155 
158 
     | 
    
         | 
| 
      
 159 
     | 
    
         
            +
            By default, `hoardable` will keep copies of records you have destroyed. You can query them
         
     | 
| 
      
 160 
     | 
    
         
            +
            specifically with:
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 163 
     | 
    
         
            +
            PostVersion.trashed.where(user_id: user.id)
         
     | 
| 
      
 164 
     | 
    
         
            +
            Post.version_class.trashed.where(user_id: user.id) # <- same as above
         
     | 
| 
      
 165 
     | 
    
         
            +
            ```
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
       156 
167 
     | 
    
         
             
            If you want to look-up the version of a record at a specific time, you can use the `.at` method:
         
     | 
| 
       157 
168 
     | 
    
         | 
| 
       158 
169 
     | 
    
         
             
            ```ruby
         
     | 
| 
         @@ -169,24 +180,13 @@ Post.at(1.day.ago) # => [#<Post>, #<Post>] 
     | 
|
| 
       169 
180 
     | 
    
         
             
            ```
         
     | 
| 
       170 
181 
     | 
    
         | 
| 
       171 
182 
     | 
    
         
             
            This will return an ActiveRecord scoped query of all `Post` and `PostVersion` records that were
         
     | 
| 
       172 
     | 
    
         
            -
            valid at that time, all cast as instances of `Post`.
         
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
            There is also an `at` method on `Hoardable` itself for more complex and experimental temporal
         
     | 
| 
       175 
     | 
    
         
            -
            resource querying. See [Relationships](#relationships) for more.
         
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
            By default, `hoardable` will keep copies of records you have destroyed. You can query them
         
     | 
| 
       178 
     | 
    
         
            -
            specifically with:
         
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       181 
     | 
    
         
            -
            PostVersion.trashed.where(user_id: user.id)
         
     | 
| 
       182 
     | 
    
         
            -
            Post.version_class.trashed.where(user_id: user.id) # <- same as above
         
     | 
| 
       183 
     | 
    
         
            -
            ```
         
     | 
| 
      
 183 
     | 
    
         
            +
            valid at that time, all cast as instances of `Post`. Updates to the versions table are forbidden in
         
     | 
| 
      
 184 
     | 
    
         
            +
            this case by a database trigger.
         
     | 
| 
       184 
185 
     | 
    
         | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
            `created_at` timestamp column. If this is missing, an error will be raised.
         
     | 
| 
      
 186 
     | 
    
         
            +
            There is also `Hoardable.at` for more complex and experimental temporal resource querying. See
         
     | 
| 
      
 187 
     | 
    
         
            +
            [Relationships](#relationships) for more.
         
     | 
| 
       188 
188 
     | 
    
         | 
| 
       189 
     | 
    
         
            -
            ### Tracking  
     | 
| 
      
 189 
     | 
    
         
            +
            ### Tracking contextual data
         
     | 
| 
       190 
190 
     | 
    
         | 
| 
       191 
191 
     | 
    
         
             
            You’ll often want to track contextual data about the creation of a version. There are 2 options that
         
     | 
| 
       192 
192 
     | 
    
         
             
            can be provided for tracking this:
         
     | 
| 
         @@ -194,8 +194,7 @@ can be provided for tracking this: 
     | 
|
| 
       194 
194 
     | 
    
         
             
            - `:whodunit` - an identifier for who/what is responsible for creating the version
         
     | 
| 
       195 
195 
     | 
    
         
             
            - `:meta` - any other contextual information you’d like to store along with the version
         
     | 
| 
       196 
196 
     | 
    
         | 
| 
       197 
     | 
    
         
            -
            This information is stored in a `jsonb` column. Each  
     | 
| 
       198 
     | 
    
         
            -
            choosing.
         
     | 
| 
      
 197 
     | 
    
         
            +
            This information is stored in a `jsonb` column. Each value can be the data type of your choosing.
         
     | 
| 
       199 
198 
     | 
    
         | 
| 
       200 
199 
     | 
    
         
             
            One convenient way to assign contextual data to these is by defining a proc in an initializer, i.e.:
         
     | 
| 
       201 
200 
     | 
    
         | 
| 
         @@ -210,16 +209,7 @@ Current.set(user: User.find(123)) do 
     | 
|
| 
       210 
209 
     | 
    
         
             
            end
         
     | 
| 
       211 
210 
     | 
    
         
             
            ```
         
     | 
| 
       212 
211 
     | 
    
         | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
       215 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       216 
     | 
    
         
            -
            Hoardable.meta = {note: "reverting due to accidental deletion"}
         
     | 
| 
       217 
     | 
    
         
            -
            post.update!(title: "We’re back!")
         
     | 
| 
       218 
     | 
    
         
            -
            Hoardable.meta = nil
         
     | 
| 
       219 
     | 
    
         
            -
            post.reload.versions.last.hoardable_meta['note'] # => "reverting due to accidental deletion"
         
     | 
| 
       220 
     | 
    
         
            -
            ```
         
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
            A more useful pattern would be to use `Hoardable.with` to set the context around a block. For
         
     | 
| 
      
 212 
     | 
    
         
            +
            Another useful pattern would be to use `Hoardable.with` to set the context around a block. For
         
     | 
| 
       223 
213 
     | 
    
         
             
            example, you could have the following in your `ApplicationController`:
         
     | 
| 
       224 
214 
     | 
    
         | 
| 
       225 
215 
     | 
    
         
             
            ```ruby
         
     | 
| 
         @@ -229,31 +219,27 @@ class ApplicationController < ActionController::Base 
     | 
|
| 
       229 
219 
     | 
    
         
             
              private
         
     | 
| 
       230 
220 
     | 
    
         | 
| 
       231 
221 
     | 
    
         
             
              def use_hoardable_context
         
     | 
| 
       232 
     | 
    
         
            -
                Hoardable.with(whodunit: current_user.id, meta: {request_uuid: request.uuid}) do
         
     | 
| 
      
 222 
     | 
    
         
            +
                Hoardable.with(whodunit: current_user.id, meta: { request_uuid: request.uuid }) do
         
     | 
| 
       233 
223 
     | 
    
         
             
                  yield
         
     | 
| 
       234 
224 
     | 
    
         
             
                end
         
     | 
| 
       235 
     | 
    
         
            -
                # `Hoardable.whodunit` and `Hoardable.meta` are back to nil or their previously set values
         
     | 
| 
       236 
225 
     | 
    
         
             
              end
         
     | 
| 
       237 
226 
     | 
    
         
             
            end
         
     | 
| 
       238 
227 
     | 
    
         
             
            ```
         
     | 
| 
       239 
228 
     | 
    
         | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
       242 
     | 
    
         
            -
            ` 
     | 
| 
       243 
     | 
    
         
            -
            in the same database transaction with a shared and unique `event_uuid` for that transaction. These
         
     | 
| 
       244 
     | 
    
         
            -
            values are available as:
         
     | 
| 
      
 229 
     | 
    
         
            +
            [ActiveRecord changes](https://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes)
         
     | 
| 
      
 230 
     | 
    
         
            +
            are also automatically captured along with the `operation` that caused the version (`update` or
         
     | 
| 
      
 231 
     | 
    
         
            +
            `delete`). These values are available as:
         
     | 
| 
       245 
232 
     | 
    
         | 
| 
       246 
233 
     | 
    
         
             
            ```ruby
         
     | 
| 
       247 
     | 
    
         
            -
            version.changes
         
     | 
| 
       248 
     | 
    
         
            -
            version.hoardable_operation
         
     | 
| 
       249 
     | 
    
         
            -
            version.hoardable_event_uuid
         
     | 
| 
      
 234 
     | 
    
         
            +
            version.changes # => { "title"=> ["Title", "New Title"] }
         
     | 
| 
      
 235 
     | 
    
         
            +
            version.hoardable_operation # => "update"
         
     | 
| 
       250 
236 
     | 
    
         
             
            ```
         
     | 
| 
       251 
237 
     | 
    
         | 
| 
       252 
238 
     | 
    
         
             
            ### Model Callbacks
         
     | 
| 
       253 
239 
     | 
    
         | 
| 
       254 
240 
     | 
    
         
             
            Sometimes you might want to do something with a version after it gets inserted to the database. You
         
     | 
| 
       255 
241 
     | 
    
         
             
            can access it in `after_versioned` callbacks on the source record as `hoardable_version`. These
         
     | 
| 
       256 
     | 
    
         
            -
            happen within `ActiveRecord 
     | 
| 
      
 242 
     | 
    
         
            +
            happen within `ActiveRecord#save`'s transaction.
         
     | 
| 
       257 
243 
     | 
    
         | 
| 
       258 
244 
     | 
    
         
             
            There are also `after_reverted` and `after_untrashed` callbacks available as well, which are called
         
     | 
| 
       259 
245 
     | 
    
         
             
            on the source record after a version is reverted or untrashed.
         
     | 
| 
         @@ -286,9 +272,9 @@ end 
     | 
|
| 
       286 
272 
     | 
    
         
             
            The configurable options are:
         
     | 
| 
       287 
273 
     | 
    
         | 
| 
       288 
274 
     | 
    
         
             
            ```ruby
         
     | 
| 
       289 
     | 
    
         
            -
            Hoardable.enabled # =>  
     | 
| 
       290 
     | 
    
         
            -
            Hoardable.version_updates # =>  
     | 
| 
       291 
     | 
    
         
            -
            Hoardable.save_trash # =>  
     | 
| 
      
 275 
     | 
    
         
            +
            Hoardable.enabled # => true
         
     | 
| 
      
 276 
     | 
    
         
            +
            Hoardable.version_updates # => true
         
     | 
| 
      
 277 
     | 
    
         
            +
            Hoardable.save_trash # => true
         
     | 
| 
       292 
278 
     | 
    
         
             
            ```
         
     | 
| 
       293 
279 
     | 
    
         | 
| 
       294 
280 
     | 
    
         
             
            `Hoardable.enabled` globally controls whether versions will be ever be created.
         
     | 
| 
         @@ -299,7 +285,7 @@ Hoardable.save_trash # => default true 
     | 
|
| 
       299 
285 
     | 
    
         
             
            When this is set to `false`, all versions of a source record will be deleted when the record is
         
     | 
| 
       300 
286 
     | 
    
         
             
            destroyed.
         
     | 
| 
       301 
287 
     | 
    
         | 
| 
       302 
     | 
    
         
            -
            If you would like to temporarily set a config  
     | 
| 
      
 288 
     | 
    
         
            +
            If you would like to temporarily set a config value, you can use `Hoardable.with`:
         
     | 
| 
       303 
289 
     | 
    
         | 
| 
       304 
290 
     | 
    
         
             
            ```ruby
         
     | 
| 
       305 
291 
     | 
    
         
             
            Hoardable.with(enabled: false) do
         
     | 
| 
         @@ -325,12 +311,11 @@ Comment.with_hoardable_config(version_updates: true) do 
     | 
|
| 
       325 
311 
     | 
    
         
             
            end
         
     | 
| 
       326 
312 
     | 
    
         
             
            ```
         
     | 
| 
       327 
313 
     | 
    
         | 
| 
       328 
     | 
    
         
            -
             
     | 
| 
       329 
     | 
    
         
            -
            `Hoardable` config.
         
     | 
| 
      
 314 
     | 
    
         
            +
            Model-level configuration overrides global configuration.
         
     | 
| 
       330 
315 
     | 
    
         | 
| 
       331 
316 
     | 
    
         
             
            ## Relationships
         
     | 
| 
       332 
317 
     | 
    
         | 
| 
       333 
     | 
    
         
            -
            ###  
     | 
| 
      
 318 
     | 
    
         
            +
            ### `belongs_to`
         
     | 
| 
       334 
319 
     | 
    
         | 
| 
       335 
320 
     | 
    
         
             
            Sometimes you’ll have a record that belongs to a parent record that you’ll trash. Now the child
         
     | 
| 
       336 
321 
     | 
    
         
             
            record’s foreign key will point to the non-existent trashed version of the parent. If you would like
         
     | 
| 
         @@ -338,17 +323,28 @@ to have `belongs_to` resolve to the trashed parent model in this case, you can g 
     | 
|
| 
       338 
323 
     | 
    
         
             
            `trashable: true`:
         
     | 
| 
       339 
324 
     | 
    
         | 
| 
       340 
325 
     | 
    
         
             
            ```ruby
         
     | 
| 
      
 326 
     | 
    
         
            +
            class Post
         
     | 
| 
      
 327 
     | 
    
         
            +
              include Hoardable::Model
         
     | 
| 
      
 328 
     | 
    
         
            +
              has_many :comments, dependent: nil
         
     | 
| 
      
 329 
     | 
    
         
            +
            end
         
     | 
| 
      
 330 
     | 
    
         
            +
             
     | 
| 
       341 
331 
     | 
    
         
             
            class Comment
         
     | 
| 
       342 
332 
     | 
    
         
             
              include Hoardable::Associations # <- This includes is not required if this model already includes `Hoardable::Model`
         
     | 
| 
       343 
333 
     | 
    
         
             
              belongs_to :post, trashable: true
         
     | 
| 
       344 
334 
     | 
    
         
             
            end
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
            post = Post.create!(title: "Title")
         
     | 
| 
      
 337 
     | 
    
         
            +
            comment = post.comments.create!(body: "Comment")
         
     | 
| 
      
 338 
     | 
    
         
            +
            post.destroy!
         
     | 
| 
      
 339 
     | 
    
         
            +
            comment.post # => #<PostVersion>
         
     | 
| 
       345 
340 
     | 
    
         
             
            ```
         
     | 
| 
       346 
341 
     | 
    
         | 
| 
       347 
     | 
    
         
            -
            ###  
     | 
| 
      
 342 
     | 
    
         
            +
            ### `has_many` & `has_one`
         
     | 
| 
       348 
343 
     | 
    
         | 
| 
       349 
     | 
    
         
            -
            Sometimes you'll have a Hoardable record that `has_one` or `has_many` other Hoardable records and 
     | 
| 
       350 
     | 
    
         
            -
            want to know the state of both the parent record and the children at a certain point in time. 
     | 
| 
       351 
     | 
    
         
            -
            this by adding `hoardable: true` to the `has_many` relationship and using the 
     | 
| 
      
 344 
     | 
    
         
            +
            Sometimes you'll have a Hoardable record that `has_one` or `has_many` other Hoardable records and
         
     | 
| 
      
 345 
     | 
    
         
            +
            you’ll want to know the state of both the parent record and the children at a certain point in time.
         
     | 
| 
      
 346 
     | 
    
         
            +
            You can accomplish this by adding `hoardable: true` to the `has_many` relationship and using the
         
     | 
| 
      
 347 
     | 
    
         
            +
            `Hoardable.at` method:
         
     | 
| 
       352 
348 
     | 
    
         | 
| 
       353 
349 
     | 
    
         
             
            ```ruby
         
     | 
| 
       354 
350 
     | 
    
         
             
            class Post
         
     | 
| 
         @@ -364,6 +360,7 @@ post = Post.create!(title: "Title") 
     | 
|
| 
       364 
360 
     | 
    
         
             
            comment1 = post.comments.create!(body: "Comment")
         
     | 
| 
       365 
361 
     | 
    
         
             
            comment2 = post.comments.create!(body: "Comment")
         
     | 
| 
       366 
362 
     | 
    
         
             
            datetime = DateTime.current
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
       367 
364 
     | 
    
         
             
            comment2.destroy!
         
     | 
| 
       368 
365 
     | 
    
         
             
            post.update!(title: "New Title")
         
     | 
| 
       369 
366 
     | 
    
         
             
            post_id = post.id # 1
         
     | 
| 
         @@ -372,37 +369,31 @@ Hoardable.at(datetime) do 
     | 
|
| 
       372 
369 
     | 
    
         
             
              post = Post.find(post_id)
         
     | 
| 
       373 
370 
     | 
    
         
             
              post.title # => "Title"
         
     | 
| 
       374 
371 
     | 
    
         
             
              post.comments.size # => 2
         
     | 
| 
       375 
     | 
    
         
            -
              post.id # => 2
         
     | 
| 
       376 
372 
     | 
    
         
             
              post.version? # => true
         
     | 
| 
      
 373 
     | 
    
         
            +
              post.id # => 2
         
     | 
| 
       377 
374 
     | 
    
         
             
              post.hoardable_id # => 1
         
     | 
| 
       378 
375 
     | 
    
         
             
            end
         
     | 
| 
       379 
376 
     | 
    
         
             
            ```
         
     | 
| 
       380 
377 
     | 
    
         | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
       382 
     | 
    
         
            -
             
     | 
| 
       383 
     | 
    
         
            -
            purposes of your business logic (serialization, rendering views, exporting, etc). Don’t fret - you
         
     | 
| 
       384 
     | 
    
         
            -
            will not be able to commit any updates to the version, even though it is masquerading as a `Post`
         
     | 
| 
       385 
     | 
    
         
            -
            because a database trigger won’t allow it.
         
     | 
| 
       386 
     | 
    
         
            -
             
     | 
| 
       387 
     | 
    
         
            -
            If you are ever unsure if a Hoardable record is a source record or a version, you can be sure by
         
     | 
| 
       388 
     | 
    
         
            -
            calling `version?` on it. If you want to get the true original source record ID, you can call
         
     | 
| 
       389 
     | 
    
         
            -
            `hoardable_id`.
         
     | 
| 
       390 
     | 
    
         
            -
             
     | 
| 
       391 
     | 
    
         
            -
            _*Note*:_ `Hoardable.at` is still very experimental and is potentially not performant for querying
         
     | 
| 
       392 
     | 
    
         
            -
            large data sets.
         
     | 
| 
      
 378 
     | 
    
         
            +
            _*Note*:_ `Hoardable.at` is experimental and potentially not performant for querying very large data
         
     | 
| 
      
 379 
     | 
    
         
            +
            sets.
         
     | 
| 
       393 
380 
     | 
    
         | 
| 
       394 
381 
     | 
    
         
             
            ### Cascading Untrashing
         
     | 
| 
       395 
382 
     | 
    
         | 
| 
       396 
383 
     | 
    
         
             
            Sometimes you’ll trash something that `has_many :children, dependent: :destroy` and if you untrash
         
     | 
| 
       397 
     | 
    
         
            -
            the parent record, you’ll want to also untrash the children. Whenever a hoardable  
     | 
| 
       398 
     | 
    
         
            -
             
     | 
| 
       399 
     | 
    
         
            -
            transaction 
     | 
| 
       400 
     | 
    
         
            -
             
     | 
| 
      
 384 
     | 
    
         
            +
            the parent record, you’ll want to also untrash the children. Whenever a hoardable versions are
         
     | 
| 
      
 385 
     | 
    
         
            +
            created, it will share a unique event UUID for all other versions created in the same database
         
     | 
| 
      
 386 
     | 
    
         
            +
            transaction. That way, when you `untrash!` a record, you could find and `untrash!` records that were
         
     | 
| 
      
 387 
     | 
    
         
            +
            trashed with it:
         
     | 
| 
       401 
388 
     | 
    
         | 
| 
       402 
389 
     | 
    
         
             
            ```ruby
         
     | 
| 
      
 390 
     | 
    
         
            +
            class Comment < ActiveRecord::Base
         
     | 
| 
      
 391 
     | 
    
         
            +
              include Hoardable::Model
         
     | 
| 
      
 392 
     | 
    
         
            +
            end
         
     | 
| 
      
 393 
     | 
    
         
            +
             
     | 
| 
       403 
394 
     | 
    
         
             
            class Post < ActiveRecord::Base
         
     | 
| 
       404 
395 
     | 
    
         
             
              include Hoardable::Model
         
     | 
| 
       405 
     | 
    
         
            -
              has_many :comments, hoardable: true, dependent: :destroy 
     | 
| 
      
 396 
     | 
    
         
            +
              has_many :comments, hoardable: true, dependent: :destroy
         
     | 
| 
       406 
397 
     | 
    
         | 
| 
       407 
398 
     | 
    
         
             
              after_untrashed do
         
     | 
| 
       408 
399 
     | 
    
         
             
                Comment
         
     | 
| 
         @@ -430,8 +421,7 @@ Then in your model include `Hoardable::Model` and provide the `hoardable: true` 
     | 
|
| 
       430 
421 
     | 
    
         
             
            ```ruby
         
     | 
| 
       431 
422 
     | 
    
         
             
            class Post < ActiveRecord::Base
         
     | 
| 
       432 
423 
     | 
    
         
             
              include Hoardable::Model # or `Hoardable::Associations` if you don't need `PostVersion`
         
     | 
| 
       433 
     | 
    
         
            -
              has_rich_text :content, hoardable: true
         
     | 
| 
       434 
     | 
    
         
            -
              # alternately, this could be `has_hoardable_rich_text :content`
         
     | 
| 
      
 424 
     | 
    
         
            +
              has_rich_text :content, hoardable: true # or `has_hoardable_rich_text :content`
         
     | 
| 
       435 
425 
     | 
    
         
             
            end
         
     | 
| 
       436 
426 
     | 
    
         
             
            ```
         
     | 
| 
       437 
427 
     | 
    
         | 
| 
         @@ -448,19 +438,18 @@ Hoardable.at(datetime) do 
     | 
|
| 
       448 
438 
     | 
    
         
             
            end
         
     | 
| 
       449 
439 
     | 
    
         
             
            ```
         
     | 
| 
       450 
440 
     | 
    
         | 
| 
       451 
     | 
    
         
            -
            ## Known  
     | 
| 
      
 441 
     | 
    
         
            +
            ## Known gotchas
         
     | 
| 
       452 
442 
     | 
    
         | 
| 
       453 
     | 
    
         
            -
            ### Rails  
     | 
| 
      
 443 
     | 
    
         
            +
            ### Rails fixtures
         
     | 
| 
       454 
444 
     | 
    
         | 
| 
       455 
445 
     | 
    
         
             
            Rails uses a method called
         
     | 
| 
       456 
446 
     | 
    
         
             
            [`disable_referential_integrity`](https://github.com/rails/rails/blob/06e9fbd954ab113108a7982357553fdef285bff1/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb#L7)
         
     | 
| 
       457 
447 
     | 
    
         
             
            when inserting fixtures into the database. This disables PostgreSQL triggers, which Hoardable relies
         
     | 
| 
       458 
448 
     | 
    
         
             
            on for assigning `hoardable_id` from the primary key’s value. If you would still like to use
         
     | 
| 
       459 
449 
     | 
    
         
             
            fixtures, you must specify the primary key’s value and `hoardable_id` to the same identifier value
         
     | 
| 
       460 
     | 
    
         
            -
            in the fixture. 
     | 
| 
       461 
     | 
    
         
            -
            [`world_factory`](https://github.com/FutureProofRetail/world_factory) however.
         
     | 
| 
      
 450 
     | 
    
         
            +
            in the fixture.
         
     | 
| 
       462 
451 
     | 
    
         | 
| 
       463 
     | 
    
         
            -
            ## Gem  
     | 
| 
      
 452 
     | 
    
         
            +
            ## Gem comparison
         
     | 
| 
       464 
453 
     | 
    
         | 
| 
       465 
454 
     | 
    
         
             
            #### [`paper_trail`](https://github.com/paper-trail-gem/paper_trail)
         
     | 
| 
       466 
455 
     | 
    
         | 
| 
         @@ -507,11 +496,18 @@ Instead of storing the previous versions or changes in a separate table, it stor 
     | 
|
| 
       507 
496 
     | 
    
         
             
            proprietary JSON format directly on the database row of the record itself. If does not support soft
         
     | 
| 
       508 
497 
     | 
    
         
             
            deletion.
         
     | 
| 
       509 
498 
     | 
    
         | 
| 
      
 499 
     | 
    
         
            +
            ## Testing
         
     | 
| 
      
 500 
     | 
    
         
            +
             
     | 
| 
      
 501 
     | 
    
         
            +
            Hoardable is tested against a matrix of Ruby 3 versions and Rails 7 & 8. To run tests locally, run:
         
     | 
| 
      
 502 
     | 
    
         
            +
             
     | 
| 
      
 503 
     | 
    
         
            +
            ```
         
     | 
| 
      
 504 
     | 
    
         
            +
            rake
         
     | 
| 
      
 505 
     | 
    
         
            +
            ```
         
     | 
| 
      
 506 
     | 
    
         
            +
             
     | 
| 
       510 
507 
     | 
    
         
             
            ## Contributing
         
     | 
| 
       511 
508 
     | 
    
         | 
| 
       512 
509 
     | 
    
         
             
            Bug reports and pull requests are welcome on GitHub at https://github.com/waymondo/hoardable.
         
     | 
| 
       513 
510 
     | 
    
         | 
| 
       514 
511 
     | 
    
         
             
            ## License
         
     | 
| 
       515 
512 
     | 
    
         | 
| 
       516 
     | 
    
         
            -
            The gem is available as open source under the terms of the [MIT
         
     | 
| 
       517 
     | 
    
         
            -
            License](https://opensource.org/licenses/MIT).
         
     | 
| 
      
 513 
     | 
    
         
            +
            The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
         
     | 
| 
         @@ -37,6 +37,12 @@ module Hoardable 
     | 
|
| 
       37 
37 
     | 
    
         
             
                end
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
                no_tasks do
         
     | 
| 
      
 40 
     | 
    
         
            +
                  def table_name
         
     | 
| 
      
 41 
     | 
    
         
            +
                    class_name.singularize.constantize.table_name
         
     | 
| 
      
 42 
     | 
    
         
            +
                  rescue StandardError
         
     | 
| 
      
 43 
     | 
    
         
            +
                    super
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       40 
46 
     | 
    
         
             
                  def foreign_key_type
         
     | 
| 
       41 
47 
     | 
    
         
             
                    options[:foreign_key_type] ||
         
     | 
| 
       42 
48 
     | 
    
         
             
                      class_name.singularize.constantize.columns.find { |col| col.name == primary_key }.sql_type
         
     | 
| 
         @@ -40,10 +40,16 @@ module Hoardable 
     | 
|
| 
       40 
40 
     | 
    
         
             
                end
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                private def hoardable_maybe_add_only(o, collector)
         
     | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
       44 
     | 
    
         
            -
                  return if Hoardable.instance_variable_get("@at")
         
     | 
| 
      
 43 
     | 
    
         
            +
                  left = o.left
         
     | 
| 
       45 
44 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
                   
     | 
| 
      
 45 
     | 
    
         
            +
                  if left.is_a?(Arel::Nodes::TableAlias)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    hoardable_maybe_add_only(left, collector)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  else
         
     | 
| 
      
 48 
     | 
    
         
            +
                    return unless left.instance_variable_get("@klass").in?(Hoardable::REGISTRY)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    return if Hoardable.instance_variable_get("@at")
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    collector << "ONLY "
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
       47 
53 
     | 
    
         
             
                end
         
     | 
| 
       48 
54 
     | 
    
         
             
              end
         
     | 
| 
       49 
55 
     | 
    
         
             
            end
         
     | 
    
        data/lib/hoardable/has_one.rb
    CHANGED
    
    | 
         @@ -9,13 +9,13 @@ module Hoardable 
     | 
|
| 
       9 
9 
     | 
    
         
             
                  def has_one(*args)
         
     | 
| 
       10 
10 
     | 
    
         
             
                    options = args.extract_options!
         
     | 
| 
       11 
11 
     | 
    
         
             
                    hoardable = options.delete(:hoardable)
         
     | 
| 
       12 
     | 
    
         
            -
                    association = super(*args, **options)
         
     | 
| 
       13 
12 
     | 
    
         
             
                    name = args.first
         
     | 
| 
       14 
     | 
    
         
            -
                     
     | 
| 
      
 13 
     | 
    
         
            +
                    association = super(*args, **options).symbolize_keys[name]
         
     | 
| 
      
 14 
     | 
    
         
            +
                    return unless hoardable || (association.options[:class_name].match?(/RichText$/))
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                    class_eval <<-RUBY, __FILE__, __LINE__ + 1
         
     | 
| 
       17 
17 
     | 
    
         
             
                      def #{name}
         
     | 
| 
       18 
     | 
    
         
            -
                        reflection = _reflections[ 
     | 
| 
      
 18 
     | 
    
         
            +
                        reflection = _reflections.symbolize_keys[:#{name}]
         
     | 
| 
       19 
19 
     | 
    
         
             
                        return super if reflection.klass.name.match?(/^ActionText/)
         
     | 
| 
       20 
20 
     | 
    
         
             
                        return super unless (timestamp = hoardable_client.has_one_at_timestamp)
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
         @@ -4,7 +4,7 @@ module Hoardable 
     | 
|
| 
       4 
4 
     | 
    
         
             
              module SchemaStatements
         
     | 
| 
       5 
5 
     | 
    
         
             
                def table_options(table_name)
         
     | 
| 
       6 
6 
     | 
    
         
             
                  options = super || {}
         
     | 
| 
       7 
     | 
    
         
            -
                  if inherited_table_names = parent_table_names(table_name)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  if !options[:options] && (inherited_table_names = parent_table_names(table_name))
         
     | 
| 
       8 
8 
     | 
    
         
             
                    options[:options] = "INHERITS (#{inherited_table_names.join(", ")})"
         
     | 
| 
       9 
9 
     | 
    
         
             
                  end
         
     | 
| 
       10 
10 
     | 
    
         
             
                  options
         
     | 
    
        data/lib/hoardable/version.rb
    CHANGED
    
    
    
        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.16.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: 2024- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2024-10-11 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: activerecord
         
     | 
| 
         @@ -17,9 +17,6 @@ dependencies: 
     | 
|
| 
       17 
17 
     | 
    
         
             
                - - ">="
         
     | 
| 
       18 
18 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       19 
19 
     | 
    
         
             
                    version: '7'
         
     | 
| 
       20 
     | 
    
         
            -
                - - "<"
         
     | 
| 
       21 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       22 
     | 
    
         
            -
                    version: '8'
         
     | 
| 
       23 
20 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       24 
21 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       25 
22 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -27,9 +24,6 @@ dependencies: 
     | 
|
| 
       27 
24 
     | 
    
         
             
                - - ">="
         
     | 
| 
       28 
25 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       29 
26 
     | 
    
         
             
                    version: '7'
         
     | 
| 
       30 
     | 
    
         
            -
                - - "<"
         
     | 
| 
       31 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       32 
     | 
    
         
            -
                    version: '8'
         
     | 
| 
       33 
27 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       34 
28 
     | 
    
         
             
              name: activesupport
         
     | 
| 
       35 
29 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -37,9 +31,6 @@ dependencies: 
     | 
|
| 
       37 
31 
     | 
    
         
             
                - - ">="
         
     | 
| 
       38 
32 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       39 
33 
     | 
    
         
             
                    version: '7'
         
     | 
| 
       40 
     | 
    
         
            -
                - - "<"
         
     | 
| 
       41 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       42 
     | 
    
         
            -
                    version: '8'
         
     | 
| 
       43 
34 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       44 
35 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       45 
36 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -47,9 +38,6 @@ dependencies: 
     | 
|
| 
       47 
38 
     | 
    
         
             
                - - ">="
         
     | 
| 
       48 
39 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       49 
40 
     | 
    
         
             
                    version: '7'
         
     | 
| 
       50 
     | 
    
         
            -
                - - "<"
         
     | 
| 
       51 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       52 
     | 
    
         
            -
                    version: '8'
         
     | 
| 
       53 
41 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       54 
42 
     | 
    
         
             
              name: railties
         
     | 
| 
       55 
43 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -57,9 +45,6 @@ dependencies: 
     | 
|
| 
       57 
45 
     | 
    
         
             
                - - ">="
         
     | 
| 
       58 
46 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       59 
47 
     | 
    
         
             
                    version: '7'
         
     | 
| 
       60 
     | 
    
         
            -
                - - "<"
         
     | 
| 
       61 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       62 
     | 
    
         
            -
                    version: '8'
         
     | 
| 
       63 
48 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       64 
49 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       65 
50 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -67,9 +52,6 @@ dependencies: 
     | 
|
| 
       67 
52 
     | 
    
         
             
                - - ">="
         
     | 
| 
       68 
53 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       69 
54 
     | 
    
         
             
                    version: '7'
         
     | 
| 
       70 
     | 
    
         
            -
                - - "<"
         
     | 
| 
       71 
     | 
    
         
            -
                  - !ruby/object:Gem::Version
         
     | 
| 
       72 
     | 
    
         
            -
                    version: '8'
         
     | 
| 
       73 
55 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       74 
56 
     | 
    
         
             
              name: fx
         
     | 
| 
       75 
57 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -177,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       177 
159 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       178 
160 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       179 
161 
     | 
    
         
             
            requirements: []
         
     | 
| 
       180 
     | 
    
         
            -
            rubygems_version: 3.5. 
     | 
| 
      
 162 
     | 
    
         
            +
            rubygems_version: 3.5.6
         
     | 
| 
       181 
163 
     | 
    
         
             
            signing_key:
         
     | 
| 
       182 
164 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       183 
165 
     | 
    
         
             
            summary: An ActiveRecord extension for versioning and soft-deletion of records in
         
     |