Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
Jared Beck | ccf0183088 | |
Jared Beck | bce8b193c5 | |
Tim Connor | 172ac1d747 | |
Jared Beck | e71c65604f | |
Jared Beck | fd35de6eb5 | |
Jared Beck | 3f0e3aba2e | |
Jared Beck | 6eb5c39e7e | |
Jared Beck | b82256d5ef | |
Daniel Bernier | a14a0e9e12 |
|
@ -48,29 +48,18 @@ Testing is a little awkward because the test suite:
|
|||
1. Contains a "dummy" rails app with three databases (test, foo, and bar)
|
||||
1. Supports three different RDBMS': sqlite, mysql, and postgres
|
||||
|
||||
### Test sqlite, AR 6
|
||||
### Test
|
||||
|
||||
For most development, testing with sqlite only is easiest and sufficient. CI
|
||||
will run the rest.
|
||||
|
||||
```
|
||||
DB=sqlite bundle exec appraisal rails-6.0 rake
|
||||
```
|
||||
|
||||
### Test sqlite, AR 5
|
||||
|
||||
```
|
||||
DB=sqlite bundle exec appraisal rails-5.2 rake
|
||||
```
|
||||
|
||||
### Test mysql, AR 5
|
||||
|
||||
```
|
||||
DB=mysql bundle exec appraisal rails-5.2 rake
|
||||
```
|
||||
|
||||
### Test postgres, AR 5
|
||||
|
||||
```
|
||||
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
|
||||
createuser --superuser postgres
|
||||
DB=postgres bundle exec appraisal rails-5.2 rake
|
||||
DB=postgres bundle exec appraisal rails-7.0 rake
|
||||
```
|
||||
|
||||
## The dummy_app
|
||||
|
@ -80,7 +69,7 @@ In the rare event you need a `console` in the `dummy_app`:
|
|||
```
|
||||
cd spec/dummy_app
|
||||
cp config/database.mysql.yml config/database.yml
|
||||
BUNDLE_GEMFILE='../../gemfiles/rails_5.2.gemfile' bin/rails console -e test
|
||||
BUNDLE_GEMFILE='../../gemfiles/rails_7.0.gemfile' bin/rails console -e test
|
||||
```
|
||||
|
||||
## Adding new schema
|
||||
|
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
# See "Lowest supported ruby version" in CONTRIBUTING.md
|
||||
ruby-version: '2.6'
|
||||
ruby-version: '2.7'
|
||||
- name: Bundle
|
||||
run: |
|
||||
gem install bundler
|
||||
|
@ -59,25 +59,14 @@ 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_5.2', 'rails_6.0', 'rails_6.1', 'rails_7.0' ]
|
||||
gemfile: [ 'rails_6.0', 'rails_6.1', 'rails_7.0' ]
|
||||
|
||||
# To keep matrix size down, only test highest and lowest rubies.
|
||||
# Ruby 3.0 is an exception. For now, let's continue to test against 2.7
|
||||
# in case it still produces any deprecation warnings.
|
||||
#
|
||||
# See "Lowest supported ruby version" in CONTRIBUTING.md
|
||||
ruby: [ '2.6', '2.7', '3.0', '3.1' ]
|
||||
|
||||
exclude:
|
||||
# rails 5.2 requires ruby < 3.0
|
||||
# https://github.com/rails/rails/issues/40938
|
||||
- ruby: '3.0'
|
||||
gemfile: 'rails_5.2'
|
||||
- ruby: '3.1'
|
||||
gemfile: 'rails_5.2'
|
||||
# rails 7 requires ruby > 2.7
|
||||
- ruby: '2.6'
|
||||
gemfile: 'rails_7.0'
|
||||
ruby: [ '2.7', '3.0', '3.1' ]
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v2
|
||||
|
|
|
@ -23,7 +23,7 @@ AllCops:
|
|||
NewCops: enable
|
||||
|
||||
# See "Lowest supported ruby version" in CONTRIBUTING.md
|
||||
TargetRubyVersion: 2.6
|
||||
TargetRubyVersion: 2.7
|
||||
|
||||
Layout/ArgumentAlignment:
|
||||
EnforcedStyle: with_fixed_indentation
|
||||
|
|
|
@ -8,12 +8,6 @@
|
|||
# > appraisal. If something is specified in both the Gemfile and an appraisal,
|
||||
# > the version from the appraisal takes precedence.
|
||||
# > https://github.com/thoughtbot/appraisal
|
||||
#
|
||||
#
|
||||
appraise "rails-5.2" do
|
||||
gem "rails", "~> 5.2.4"
|
||||
gem "rails-controller-testing", "~> 1.0.2"
|
||||
end
|
||||
|
||||
appraise "rails-6.0" do
|
||||
gem "rails", "~> 6.0.3"
|
||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -7,7 +7,13 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).
|
|||
|
||||
### Breaking Changes
|
||||
|
||||
- None
|
||||
- [#1399](https://github.com/paper-trail-gem/paper_trail/pull/1399) - Same
|
||||
change re: `YAML.safe_load` as in 13.0.0, but this time for Rails 6.0 and 6.1.
|
||||
|
||||
### Dependencies
|
||||
|
||||
- Drop support for Rails 5.2, which reached EoL on 2022-06-01
|
||||
- Drop support for Ruby 2.6, which reached EoL on 2022-03-31
|
||||
|
||||
### Added
|
||||
|
||||
|
@ -21,12 +27,12 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).
|
|||
|
||||
### Breaking Changes
|
||||
|
||||
- The default serializer will now use `YAML.safe_load` unless
|
||||
- For Rails >= 7.0, the default serializer will now use `YAML.safe_load` unless
|
||||
`ActiveRecord.use_yaml_unsafe_load`. This change only affects users whose
|
||||
`versions` table has `object` or `object_changes` columns of type `text`, and
|
||||
who use the YAML serializer. People who use the JSON serializer, or those with
|
||||
`json(b)` columns, are unaffected. Please see [doc/pt_13_yaml_safe_load.md] for
|
||||
details.
|
||||
`json(b)` columns, are unaffected. Please see
|
||||
[doc/pt_13_yaml_safe_load.md](doc/pt_13_yaml_safe_load.md) for details.
|
||||
|
||||
### Added
|
||||
|
||||
|
|
26
README.md
26
README.md
|
@ -90,7 +90,7 @@ Choose version:
|
|||
|
||||
| paper_trail | branch | ruby | activerecord |
|
||||
|-------------|------------|----------|---------------|
|
||||
| unreleased | master | >= 2.6.0 | >= 5.2, < 7.1 |
|
||||
| unreleased | master | >= 2.7.0 | >= 6.0, < 7.1 |
|
||||
| 13 | 13-stable | >= 2.6.0 | >= 5.2, < 7.1 |
|
||||
| 12 | 12-stable | >= 2.6.0 | >= 5.2, < 7.1 |
|
||||
| 11 | 11-stable | >= 2.4.0 | >= 5.2, < 6.1 |
|
||||
|
@ -415,7 +415,7 @@ my_model.paper_trail.save_with_version
|
|||
|
||||
#### Ignore
|
||||
|
||||
You can `ignore` changes to certain attributes:
|
||||
If you don't want a version created when only a certain attribute changes, you can `ignore` that attribute:
|
||||
|
||||
```ruby
|
||||
class Article < ActiveRecord::Base
|
||||
|
@ -436,6 +436,8 @@ a.versions.length # 2
|
|||
a.paper_trail.previous_version.title # 'My Title'
|
||||
```
|
||||
|
||||
Note: ignored fields will be stored in the version records. If you want to keep a field out of the versions table, use [`:skip`](#skip) instead of `:ignore`; skipped fields are also implicitly ignored.
|
||||
|
||||
The `:ignore` option can also accept `Hash` arguments that we are considering deprecating.
|
||||
|
||||
```ruby
|
||||
|
@ -499,17 +501,31 @@ article being saved if a changed attribute is included in `:only` but not in
|
|||
|
||||
#### Skip
|
||||
|
||||
You can skip attributes completely with the `:skip` option. As with `:ignore`,
|
||||
If you never want a field's values in the versions table, you can `:skip` the attribute. As with `:ignore`,
|
||||
updates to these attributes will not create a version record. In addition, if a
|
||||
version record is created for some other reason, these attributes will not be
|
||||
persisted.
|
||||
|
||||
```ruby
|
||||
class Article < ActiveRecord::Base
|
||||
has_paper_trail skip: [:file_upload]
|
||||
class Author < ActiveRecord::Base
|
||||
has_paper_trail skip: [:social_security_number]
|
||||
end
|
||||
```
|
||||
|
||||
Author's social security numbers will never appear in the versions log, and if an author updates only their social security number, it won't create a version record.
|
||||
|
||||
#### Comparing `:ignore`, `:only`, and `:skip`
|
||||
|
||||
- `:only` is basically the same as `:ignore`, but its inverse.
|
||||
- `:ignore` controls whether paper_trail will create a version record or not.
|
||||
- `:skip` controls whether paper_trail will save that field with the version record.
|
||||
- Skipped fields are also implicitly ignored. paper_trail does this internally.
|
||||
- Ignored fields are not implicitly skipped.
|
||||
|
||||
So:
|
||||
- Ignore a field if you don't want a version record created when it's the only field to change.
|
||||
- Skip a field if you don't want it to be saved with any version records.
|
||||
|
||||
### 2.d. Turning PaperTrail Off
|
||||
|
||||
PaperTrail is on by default, but sometimes you don't want to record versions.
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
# This file was generated by Appraisal
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "rails", "~> 5.2.4"
|
||||
gem "rails-controller-testing", "~> 1.0.2"
|
||||
|
||||
gemspec path: "../"
|
|
@ -17,7 +17,7 @@ module PaperTrail
|
|||
# newer rails versions. Most PT users should avoid incompatible rails
|
||||
# versions.
|
||||
module Compatibility
|
||||
ACTIVERECORD_GTE = ">= 5.2" # enforced in gemspec
|
||||
ACTIVERECORD_GTE = ">= 6.0" # enforced in gemspec
|
||||
ACTIVERECORD_LT = "< 7.1" # not enforced in gemspec
|
||||
|
||||
E_INCOMPATIBLE_AR = <<-EOS
|
||||
|
|
|
@ -12,7 +12,7 @@ module PaperTrail
|
|||
if use_safe_load?
|
||||
::YAML.safe_load(
|
||||
string,
|
||||
permitted_classes: ::ActiveRecord.yaml_column_permitted_classes,
|
||||
permitted_classes: yaml_column_permitted_classes,
|
||||
aliases: true
|
||||
)
|
||||
elsif ::YAML.respond_to?(:unsafe_load)
|
||||
|
@ -39,10 +39,29 @@ module PaperTrail
|
|||
|
||||
private
|
||||
|
||||
# `use_yaml_unsafe_load` was added in 7.0.3.1, will be removed in 7.1.0?
|
||||
def use_safe_load?
|
||||
defined?(ActiveRecord.use_yaml_unsafe_load) &&
|
||||
!ActiveRecord.use_yaml_unsafe_load
|
||||
if ::ActiveRecord.gem_version >= Gem::Version.new("7.0.3.1")
|
||||
# `use_yaml_unsafe_load` may be removed in the future, at which point
|
||||
# safe loading will be the default.
|
||||
!defined?(ActiveRecord.use_yaml_unsafe_load) || !ActiveRecord.use_yaml_unsafe_load
|
||||
elsif defined?(ActiveRecord::Base.use_yaml_unsafe_load)
|
||||
# Rails 5.2.8.1, 6.0.5.1, 6.1.6.1
|
||||
!ActiveRecord::Base.use_yaml_unsafe_load
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def yaml_column_permitted_classes
|
||||
if defined?(ActiveRecord.yaml_column_permitted_classes)
|
||||
# Rails >= 7.0.3.1
|
||||
ActiveRecord.yaml_column_permitted_classes
|
||||
elsif defined?(ActiveRecord::Base.yaml_column_permitted_classes)
|
||||
# Rails 5.2.8.1, 6.0.5.1, 6.1.6.1
|
||||
ActiveRecord::Base.yaml_column_permitted_classes
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ has been destroyed.
|
|||
# about 3 years, per https://www.ruby-lang.org/en/downloads/branches/
|
||||
#
|
||||
# See "Lowest supported ruby version" in CONTRIBUTING.md
|
||||
s.required_ruby_version = ">= 2.6.0"
|
||||
s.required_ruby_version = ">= 2.7.0"
|
||||
|
||||
# We no longer specify a maximum activerecord version.
|
||||
# See discussion in paper_trail/compatibility.rb
|
||||
|
|
|
@ -13,7 +13,17 @@ require File.expand_path("boot", __dir__)
|
|||
|
||||
module Dummy
|
||||
class Application < Rails::Application
|
||||
config.load_defaults(::Rails.gem_version.segments.take(2).join("."))
|
||||
YAML_COLUMN_PERMITTED_CLASSES = [
|
||||
::ActiveRecord::Type::Time::Value,
|
||||
::ActiveSupport::TimeWithZone,
|
||||
::ActiveSupport::TimeZone,
|
||||
::BigDecimal,
|
||||
::Date,
|
||||
::Symbol,
|
||||
::Time
|
||||
].freeze
|
||||
|
||||
config.load_defaults(::ActiveRecord.gem_version.segments.take(2).join("."))
|
||||
|
||||
config.encoding = "utf-8"
|
||||
config.filter_parameters += [:password]
|
||||
|
@ -21,25 +31,14 @@ module Dummy
|
|||
config.active_support.test_order = :sorted
|
||||
config.secret_key_base = "A fox regularly kicked the screaming pile of biscuits."
|
||||
|
||||
# In rails >= 6.0, "`.represent_boolean_as_integer=` is now always true,
|
||||
# so setting this is deprecated and will be removed in Rails 6.1."
|
||||
if ::ENV["DB"] == "sqlite" &&
|
||||
::Gem::Requirement.new("~> 5.2").satisfied_by?(::Rails.gem_version)
|
||||
config.active_record.sqlite3.represent_boolean_as_integer = true
|
||||
end
|
||||
|
||||
# `use_yaml_unsafe_load` was added in 7.0.3.1, will be removed in 7.1.0?
|
||||
if ::ActiveRecord.respond_to?(:use_yaml_unsafe_load)
|
||||
# `use_yaml_unsafe_load` was added in 5.2.8.1, 6.0.5.1, 6.1.6.1, and 7.0.3.1.
|
||||
# Will be removed in 7.1.0?
|
||||
if ::ActiveRecord.respond_to?(:use_yaml_unsafe_load) # 7.0.3.1
|
||||
::ActiveRecord.use_yaml_unsafe_load = false
|
||||
::ActiveRecord.yaml_column_permitted_classes = [
|
||||
::ActiveRecord::Type::Time::Value,
|
||||
::ActiveSupport::TimeWithZone,
|
||||
::ActiveSupport::TimeZone,
|
||||
::BigDecimal,
|
||||
::Date,
|
||||
::Symbol,
|
||||
::Time
|
||||
]
|
||||
::ActiveRecord.yaml_column_permitted_classes = YAML_COLUMN_PERMITTED_CLASSES
|
||||
elsif ::ActiveRecord::Base.respond_to?(:use_yaml_unsafe_load) # 5.2.8.1, 6.0.5.1, 6.1.6.1
|
||||
::ActiveRecord::Base.use_yaml_unsafe_load = false
|
||||
::ActiveRecord::Base.yaml_column_permitted_classes = YAML_COLUMN_PERMITTED_CLASSES
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -138,7 +138,7 @@ RSpec.describe Widget, type: :model, versioning: true do
|
|||
it "have versions that are not live" do
|
||||
widget = described_class.create(name: "Henry")
|
||||
widget.update(name: "Harry")
|
||||
widget.versions.map(&:reify).compact.each do |v|
|
||||
widget.versions.filter_map(&:reify).each do |v|
|
||||
expect(v.paper_trail).not_to be_live
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,12 +24,12 @@ module PaperTrail
|
|||
end
|
||||
|
||||
it "calls the expected load method based on Psych version" do
|
||||
# `use_yaml_unsafe_load` was added in 7.0.3.1, will be removed in 7.1.0?
|
||||
if defined?(ActiveRecord.use_yaml_unsafe_load) && !ActiveRecord.use_yaml_unsafe_load
|
||||
# `use_yaml_unsafe_load` was added in 5.2.8.1, 6.0.5.1, 6.1.6.1, and 7.0.3.1
|
||||
if rails_supports_safe_load?
|
||||
allow(::YAML).to receive(:safe_load)
|
||||
described_class.load("string")
|
||||
expect(::YAML).to have_received(:safe_load)
|
||||
# Psych 4+ implements .unsafe_load
|
||||
# Psych 4+ implements .unsafe_load
|
||||
elsif ::YAML.respond_to?(:unsafe_load)
|
||||
allow(::YAML).to receive(:unsafe_load)
|
||||
described_class.load("string")
|
||||
|
@ -60,6 +60,16 @@ module PaperTrail
|
|||
expect(arel_value(matches.right)).to eq("%\narg1: Val 1\n%")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rails_supports_safe_load?
|
||||
# Rails 7.0.3.1 onwards will always support YAML safe loading
|
||||
return true if ::ActiveRecord.gem_version >= Gem::Version.new("7.0.3.1")
|
||||
|
||||
# Older Rails versions may or may not, depending on whether they have been patched.
|
||||
defined?(ActiveRecord::Base.use_yaml_unsafe_load)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ require "simplecov"
|
|||
SimpleCov.start do
|
||||
add_filter %w[Appraisals Gemfile Rakefile doc gemfiles spec]
|
||||
end
|
||||
SimpleCov.minimum_coverage(ENV["DB"] == "postgres" ? 97.3 : 92.4)
|
||||
SimpleCov.minimum_coverage(ENV["DB"] == "postgres" ? 96.8 : 92.4)
|
||||
|
||||
require "byebug"
|
||||
require_relative "support/pt_arel_helpers"
|
||||
|
|
|
@ -18,22 +18,11 @@ class PaperTrailSpecMigrator
|
|||
@migrations_path = dummy_app_migrations_dir
|
||||
end
|
||||
|
||||
# Looks like the API for programmatically running migrations will change
|
||||
# in rails 5.2. This is an undocumented change, AFAICT. Then again,
|
||||
# how many people use the programmatic interface? Most people probably
|
||||
# just use rake. Maybe we're doing it wrong.
|
||||
#
|
||||
# See also discussion in https://github.com/rails/rails/pull/40806, when
|
||||
# MigrationContext#migrate became public.
|
||||
def migrate
|
||||
if ::ActiveRecord.gem_version >= ::Gem::Version.new("6.0.0.rc2")
|
||||
::ActiveRecord::MigrationContext.new(
|
||||
@migrations_path,
|
||||
::ActiveRecord::Base.connection.schema_migration
|
||||
).migrate
|
||||
else
|
||||
::ActiveRecord::MigrationContext.new(@migrations_path).migrate
|
||||
end
|
||||
::ActiveRecord::MigrationContext.new(
|
||||
@migrations_path,
|
||||
::ActiveRecord::Base.connection.schema_migration
|
||||
).migrate
|
||||
end
|
||||
|
||||
# Generate a migration, run it, and delete it. We use this for testing the
|
||||
|
|
Loading…
Reference in New Issue