Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ For most development, testing with sqlite only is easiest and sufficient. CI
will run the rest.

```
DB=sqlite bundle exec appraisal rails-6.1 rake
DB=sqlite bundle exec appraisal rails-7.0 rake
DB=mysql bundle exec appraisal rails-7.0 rake
DB=sqlite bundle exec appraisal rails-7.1 rake
DB=sqlite bundle exec appraisal rails-8.0 rake
DB=mysql bundle exec appraisal rails-7.1 rake
createuser --superuser postgres
DB=postgres bundle exec appraisal rails-7.0 rake
DB=postgres bundle exec appraisal rails-7.1 rake
```

## The dummy_app
Expand Down
10 changes: 3 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
uses: ruby/setup-ruby@v1
with:
# See "Lowest supported ruby version" in CONTRIBUTING.md
ruby-version: '3.0'
ruby-version: '3.2'
- name: Bundle
run: |
gem install bundler
Expand Down Expand Up @@ -59,15 +59,11 @@ jobs:
# have set this up with each database as a separate job, but then we'd be
# duplicating the matrix configuration three times.
matrix:
gemfile: [ 'rails_6.1', 'rails_7.0', 'rails_7.1', 'rails_7.2', 'rails_8.0' ]
gemfile: [ 'rails_7.1', 'rails_7.2', 'rails_8.0', 'rails_8.1' ]

# To keep matrix size down, only test highest and lowest rubies.
# See "Lowest supported ruby version" in CONTRIBUTING.md
ruby: [ '3.1', '3.3' ]
exclude:
# Rails 8 requires ruby 3.2+.
- gemfile: 'rails_8.0'
ruby: '3.1'
ruby: [ '3.2', '3.4' ]
steps:
- name: Checkout source
uses: actions/checkout@v4
Expand Down
40 changes: 34 additions & 6 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require:
plugins:
- rubocop-packaging
- rubocop-performance
- rubocop-rails
Expand All @@ -23,7 +23,10 @@ AllCops:
NewCops: enable

# See "Lowest supported ruby version" in CONTRIBUTING.md
TargetRubyVersion: 3.0
TargetRubyVersion: 3.2

Gemspec/DevelopmentDependencies:
Enabled: false

Layout/ArgumentAlignment:
EnforcedStyle: with_fixed_indentation
Expand Down Expand Up @@ -65,7 +68,7 @@ Layout/SpaceAroundOperators:
# from these is of questionable value.
Metrics/AbcSize:
Exclude:
- 'spec/dummy_app/db/migrate/*'
- "spec/dummy_app/db/migrate/*"

# Not a useful metric compared to, e.g. `AbcSize`.
Metrics/BlockLength:
Expand Down Expand Up @@ -96,9 +99,13 @@ Naming/FileName:
Naming/HeredocDelimiterNaming:
Enabled: false

Naming/PredicateName:
Naming/PredicatePrefix:
AllowedMethods: has_paper_trail

# It is currently broken as of rubocop 1.77.0.
Naming/PredicateMethod:
Enabled: false

# Too subtle to lint.
# Two-letter param names are OK. Consider `send_email(to:, cc:)`.
# Even one-letter names are OK. Consider `draw_point(x, y)`.
Expand All @@ -115,6 +122,12 @@ Performance/CollectionLiteralInLoop:
Exclude:
- spec/**/*

Rails/ApplicationRecord:
Enabled: false

Rails/Delegate:
Enabled: false

# This cop only applies to app dev, not gem dev.
Rails/RakeEnvironment:
Enabled: false
Expand All @@ -123,6 +136,9 @@ Rails/RakeEnvironment:
Rails/SkipsModelValidations:
Enabled: false

RSpec/BeEq:
Enabled: false

# This cop does not seem to work in rubocop-rspec 1.28.0
RSpec/DescribeClass:
Enabled: false
Expand All @@ -133,13 +149,22 @@ RSpec/DescribeClass:
RSpec/ExampleLength:
Enabled: false

RSpec/IndexedLet:
Enabled: false

# In an ideal world, each example has a single expectation. In the real world,
# sometimes setup is a pain and you don't want to duplicate setup in multiple
# examples, or make the specs more confusing with many nested `context`s, and
# the practical thing is to have multiple expectations.
RSpec/MultipleExpectations:
Enabled: false

# It may be possible for us to use safe_load, but we'd have to pass the
# safelists, like `whitelist_classes` into our serializer, and the serializer
# interface is a public API, so that would be a breaking change.
Security/YAMLLoad:
Enabled: false

# Please use semantic style, e.g. `do` when there's a side-effect, else `{}`.
# The semantic style is too nuanced to lint, so the cop is disabled.
Style/BlockDelimiters:
Expand All @@ -150,6 +175,9 @@ Style/BlockDelimiters:
Style/DoubleNegation:
Enabled: false

Style/FetchEnvVar:
Enabled: false

# Avoid annotated tokens except in desperately complicated format strings.
# In 99% of format strings they actually make it less readable.
Style/FormatStringToken:
Expand Down Expand Up @@ -182,8 +210,8 @@ Style/IfUnlessModifier:
# - https://github.com/bbatsov/ruby-style-guide/issues/556
Style/ModuleFunction:
Exclude:
- 'lib/paper_trail/serializers/json.rb'
- 'lib/paper_trail/serializers/yaml.rb'
- "lib/paper_trail/serializers/json.rb"
- "lib/paper_trail/serializers/yaml.rb"

# Too subtle to lint. Use `format` for multiple variables. For single variables,
# use either interpolation or concatenation, whichever is easier to read.
Expand Down
20 changes: 5 additions & 15 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2022-11-26 07:45:38 UTC using RuboCop version 1.22.3.
# on 2025-03-31 23:04:51 UTC using RuboCop version 1.75.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# It may be possible for us to use safe_load, but we'd have to pass the
# safelists, like `whitelist_classes` into our serializer, and the serializer
# interface is a public API, so that would be a breaking change.
# Offense count: 13
# Cop supports --auto-correct.
Security/YAMLLoad:
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/ActiveSupportOnLoad:
Exclude:
- 'lib/paper_trail/serializers/yaml.rb'
- 'spec/models/book_spec.rb'
- 'spec/models/gadget_spec.rb'
- 'spec/models/no_object_spec.rb'
- 'spec/models/person_spec.rb'
- 'spec/models/version_spec.rb'
- 'spec/paper_trail/events/destroy_spec.rb'
- 'spec/paper_trail/serializer_spec.rb'
- "lib/paper_trail/frameworks/active_record.rb"
20 changes: 6 additions & 14 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,20 @@
# > the version from the appraisal takes precedence.
# > https://github.com/thoughtbot/appraisal

appraise "rails-6.1" do
gem "rails", "~> 6.1.0"
gem "rails-controller-testing", "~> 1.0.5"
end

appraise "rails-7.0" do
gem "rails", "~> 7.0.3.1"
gem "rails-controller-testing", "~> 1.0.5"
end

appraise "rails-7.1" do
gem "rails", "~> 7.1.0"
gem "rails-controller-testing", "~> 1.0.5"
end

appraise "rails-7.2" do
gem "rails", "~> 7.2.0"
gem "rails-controller-testing", "~> 1.0.5"
end

appraise "rails-8.0" do
gem "rails", "~> 8.0.0.rc1"
gem "rails-controller-testing", "~> 1.0.5"
gem "rails", "~> 8.0.0"
gem "sqlite3", ">= 2.1"
end

appraise "rails-8.1" do
gem "rails", "~> 8.1.0"
gem "sqlite3", ">= 2.1"
end
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,45 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).

### Breaking Changes

- None

### Added

- None

### Fixed

- None

## 17.0.0 (2025-10-24)

### Breaking Changes

- None

### Added

- `rails generate paper_trail:install` now accepts an argument for custom versions table, e.g.
`rails generate paper_trail:install CommentVersion` created `comment_versions` table
- `rails generate paper_trail:update_item_subtype` now supports custom version classes via
`--version-class-name` option, e.g. `--version-class-name=CommentVersion`

### Fixed

- None

### Dependencies

- Drop support for Rails 6.1, which [reached EoL on 2024-10-01][2]
- Drop support for Rails 7.0, which [reached EoL on 2025-04-01][2]
- Add support for Rails 8.1
- Drop support for Ruby 3.0, which [reached EoL on 2024-04-23][3]
- Drop support for Ruby 3.1, which [reached EoL on 2024-03-31][3]

## 16.0.0 (2024-11-08)

### Breaking Changes

- [#1478](https://github.com/paper-trail-gem/paper_trail/issues/1478) Do not allow
multiple `has_paper_trail` definitions for models. Previously, when `has_paper_trail`
was called on a parent and a child from STI, then possibly multiple `version` records
Expand Down
54 changes: 39 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ This is the _user guide_. See also, the

Choose version:
[Unreleased](https://github.com/paper-trail-gem/paper_trail/blob/master/README.md),
[17.0](https://github.com/paper-trail-gem/paper_trail/blob/v17.0.0/README.md),
[16.0](https://github.com/paper-trail-gem/paper_trail/blob/v16.0.0/README.md),
[15.2](https://github.com/paper-trail-gem/paper_trail/blob/v15.2.0/README.md),
[14.0](https://github.com/paper-trail-gem/paper_trail/blob/v14.0.0/README.md),
[13.0](https://github.com/paper-trail-gem/paper_trail/blob/v13.0.0/README.md),
Expand Down Expand Up @@ -68,6 +70,7 @@ Choose version:
- [6.b. Custom Serializer](#6b-custom-serializer)
- [6.c. Custom Object Changes](#6c-custom-object-changes)
- [6.d. Excluding the Object Column](#6d-excluding-the-object-column)
- [6.e. Error handling](#6e-error-handling)
- [7. Testing](#7-testing)
- [7.a. Minitest](#7a-minitest)
- [7.b. RSpec](#7b-rspec)
Expand All @@ -92,10 +95,11 @@ Choose version:

| paper_trail | ruby | activerecord |
|-------------|----------|---------------|
| unreleased | >= 3.1.0 | >= 6.1, <= 8.0 |
| 15.2 | >= 3.1.0 | >= 6.1, <= 7.2 |
| 15.1 | >= 3.1.0 | >= 6.1, <= 7.1 |
| 15 | >= 3.0.0 | >= 6.1, < 7.2 |
| unreleased | >= 3.2.0 | >= 7.1, <= 8.1 |
| 16 | >= 3.0.0 | >= 6.1, <= 8.0 |
| 15.2 | >= 3.0.0 | >= 6.1, <= 7.2 |
| 15.1 | >= 3.0.0 | >= 6.1, <= 7.1 |
| 15 | >= 3.0.0 | >= 6.1, <= 7.1 |
| 14 | >= 2.7.0 | >= 6.0, < 7.1 |
| 13 | >= 2.6.0 | >= 5.2, < 7.1 |
| 12 | >= 2.6.0 | >= 5.2, < 7.1 |
Expand Down Expand Up @@ -1151,6 +1155,8 @@ Be advised that redefining an association is an undocumented feature of Rails.
PaperTrail has one generator, `paper_trail:install`. It writes, but does not
run, a migration file. The migration creates the `versions` table.

You can provide a custom version table name e.g., for having multiple version tables. You will still need setup a custom Version class and configure it to use the custom table. See [6.a. Custom Version Classes](#6a-custom-version-classes).

#### Reference

The most up-to-date documentation for this generator can be found by running
Expand All @@ -1159,19 +1165,25 @@ convenience.

```
Usage:
rails generate paper_trail:install [options]
bin/rails generate paper_trail:install [VERSION_CLASS_NAME] [options]

Options:
[--with-changes], [--no-with-changes] # Store changeset (diff) with each version
[--uuid] # To use paper_trail with projects using uuid for id
[--skip-namespace] # Skip namespace (affects only isolated engines)
# Default: false
[--skip-collision-check] # Skip collision check
# Default: false
[--with-changes], [--no-with-changes], [--skip-with-changes] # Store changeset (diff) with each version
# Default: false
[--uuid], [--no-uuid], [--skip-uuid] # Use uuid instead of bigint for item_id type (use only if tables use UUIDs)
# Default: false

Runtime options:
-f, [--force] # Overwrite files that already exist
-p, [--pretend], [--no-pretend] # Run but do not make any changes
-q, [--quiet], [--no-quiet] # Suppress status output
-s, [--skip], [--no-skip] # Skip files that already exist
-f, [--force] # Overwrite files that already exist
-p, [--pretend], [--no-pretend], [--skip-pretend] # Run but do not make any changes
-q, [--quiet], [--no-quiet], [--skip-quiet] # Suppress status output
-s, [--skip], [--no-skip], [--skip-skip] # Skip files that already exist

Generates (but does not run) a migration to add a versions table.
Generates (but does not run) a migration to add a versions table. Can be customized by providing a Version class name. See section 5.c. Generators in README.md for more information.
```

### 5.d. Protected Attributes
Expand Down Expand Up @@ -1448,6 +1460,18 @@ The `object` column ends up storing a lot of duplicate data if you have models t
and that are updated many times. You can save ~50% of storage space by removing the column from the
versions table. It's important to note that this will disable `reify` and `where_object`.

### 6.e. Error handling

You can change the behavior of error handling when an exception is raised while creating a version, by setting the `version_error_behavior` option:

```ruby
# config/initializers/paper_trail.rb
PaperTrail.config.version_error_behavior = :legacy # (Default) Raise on create, log on update/delete.
PaperTrail.config.version_error_behavior = :log # Only log error.
PaperTrail.config.version_error_behavior = :exception # Raise exception.
PaperTrail.config.version_error_behavior = :silent # No-op.
```

## 7. Testing

You may want to turn PaperTrail off to speed up your tests. See [Turning
Expand Down Expand Up @@ -1755,8 +1779,8 @@ Released under the MIT licence.
[1]: http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
[2]: https://github.com/paper-trail-gem/paper_trail/issues/163
[3]: http://railscasts.com/episodes/255-undo-with-paper-trail
[4]: https://api.travis-ci.org/paper-trail-gem/paper_trail.svg?branch=master
[5]: https://travis-ci.org/paper-trail-gem/paper_trail
[4]: https://github.com/paper-trail-gem/paper_trail/actions/workflows/test.yml/badge.svg
[5]: https://github.com/paper-trail-gem/paper_trail/actions/workflows/test.yml
[6]: https://github.com/westonganger/paper_trail-association_tracking
[9]: https://github.com/paper-trail-gem/paper_trail/tree/3.0-stable
[10]: https://github.com/paper-trail-gem/paper_trail/tree/2.7-stable
Expand Down Expand Up @@ -1799,6 +1823,6 @@ Released under the MIT licence.
[52]: http://guides.rubyonrails.org/active_record_callbacks.html
[53]: https://badge.fury.io/rb/paper_trail.svg
[54]: https://rubygems.org/gems/paper_trail
[55]: https://api.dependabot.com/badges/compatibility_score?dependency-name=paper_trail&package-manager=bundler&version-scheme=semver
[55]: https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=paper_trail&package-manager=bundler&previous-version=15.2.0&new-version=16.0.0
[56]: https://dependabot.com/compatibility-score.html?dependency-name=paper_trail&package-manager=bundler&version-scheme=semver
[57]: https://bundler.io/v2.3/man/bundle-install.1.html
4 changes: 2 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ task :install_database_yml do
# It's tempting to use `git clean` here, but this rake task will be run by
# people working on changes that haven't been committed yet, so we have to
# be more selective with what we delete.
::FileUtils.rm("spec/dummy_app/db/database.yml", force: true)
FileUtils.rm("spec/dummy_app/db/database.yml", force: true)

FileUtils.cp(
"spec/dummy_app/config/database.#{ENV['DB']}.yml",
Expand All @@ -32,7 +32,7 @@ task :clean do
# TODO: only works locally. doesn't respect database.yml
system "dropdb --if-exists paper_trail_test > /dev/null 2>&1"
when nil, "sqlite"
::FileUtils.rm(::Dir.glob("spec/dummy_app/db/*.sqlite3"))
FileUtils.rm(Dir.glob("spec/dummy_app/db/*.sqlite3"))
else
raise "Don't know how to clean specified RDBMS: #{ENV['DB']}"
end
Expand Down
Loading
Loading