Skip to content

Instantly share code, notes, and snippets.

This bug report script demonstrates a bug with PaperTrail when the ActiveRecord model has both database and model defaults for a serialized field
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "activerecord", "~> 7.0.0"
gem "sqlite3"
# Activate the gem you are reporting the issue against.
gem "paper_trail", "~> 14.0.0"
end
require "active_record"
require "paper_trail"
require "minitest/autorun"
require "logger"
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :paper_trailed_record_ones, force: true do |t|
t.text :serialized_array_with_db_and_model_defaults_for_empty_array, default: [].to_yaml
end
create_table :paper_trailed_record_twos, force: true do |t|
t.text :serialized_array_with_db_default_for_empty_array, default: [].to_yaml
end
create_table :paper_trailed_record_threes, force: true do |t|
t.text :serialized_array_with_model_default_for_empty_array
end
create_table :paper_trailed_record_fours, force: true do |t|
t.text :serialized_array_with_db_and_model_defaults_for_filled_array, default: [1].to_yaml
end
create_table :paper_trailed_record_fives, force: true do |t|
t.text :serialized_array_with_db_default_for_filled_array, default: [1].to_yaml
end
create_table :paper_trailed_record_sixes, force: true do |t|
t.text :serialized_array_with_model_default_for_filled_array
end
create_table :paper_trailed_record_sevens, force: true do |t|
t.text :serialized_array_with_no_defaults
end
create_table :non_paper_trailed_records, force: true do |t|
t.text :serialized_array_with_db_and_model_defaults_for_empty_array, default: [].to_yaml
t.text :serialized_array_with_db_default_for_empty_array, default: [].to_yaml
t.text :serialized_array_with_model_default_for_empty_array
t.text :serialized_array_with_db_and_model_defaults_for_filled_array, default: [1].to_yaml
t.text :serialized_array_with_db_default_for_filled_array, default: [1].to_yaml
t.text :serialized_array_with_model_default_for_filled_array
t.text :serialized_array_with_no_defaults
end
create_table "versions", force: true do |t|
t.string "item_type", null: false
t.bigint "item_id", null: false
t.string "event", null: false
t.string "whodunnit"
t.text "object", limit: 1073741823
t.datetime "created_at"
t.text "object_changes", limit: 1073741823
t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id"
end
end
class PaperTrailedRecordOne < ActiveRecord::Base
has_paper_trail
serialize :serialized_array_with_db_and_model_defaults_for_empty_array, Array
attribute :serialized_array_with_db_and_model_defaults_for_empty_array, default: []
end
class PaperTrailedRecordTwo < ActiveRecord::Base
has_paper_trail
serialize :serialized_array_with_db_default_for_empty_array, Array
end
class PaperTrailedRecordThree < ActiveRecord::Base
has_paper_trail
serialize :serialized_array_with_model_default_for_empty_array, Array
attribute :serialized_array_with_model_default_for_empty_array, default: []
end
class PaperTrailedRecordFour < ActiveRecord::Base
has_paper_trail
serialize :serialized_array_with_db_and_model_defaults_for_filled_array, Array
attribute :serialized_array_with_db_and_model_defaults_for_filled_array, default: [1]
end
class PaperTrailedRecordFive < ActiveRecord::Base
has_paper_trail
serialize :serialized_array_with_db_default_for_filled_array, Array
end
class PaperTrailedRecordSix < ActiveRecord::Base
has_paper_trail
serialize :serialized_array_with_model_default_for_filled_array, Array
attribute :serialized_array_with_model_default_for_filled_array, default: [1]
end
class PaperTrailedRecordSeven < ActiveRecord::Base
has_paper_trail
serialize :serialized_array_with_no_defaults, Array
end
class NonPaperTrailedRecord < ActiveRecord::Base
serialize :serialized_array_with_db_and_model_defaults_for_empty_array, Array
attribute :serialized_array_with_db_and_model_defaults_for_empty_array, default: []
serialize :serialized_array_with_db_default_for_empty_array, Array
serialize :serialized_array_with_model_default_for_empty_array, Array
attribute :serialized_array_with_model_default_for_empty_array, default: []
serialize :serialized_array_with_db_and_model_defaults_for_filled_array, Array
attribute :serialized_array_with_db_and_model_defaults_for_filled_array, default: [1]
serialize :serialized_array_with_db_default_for_filled_array, Array
serialize :serialized_array_with_model_default_for_filled_array, Array
attribute :serialized_array_with_model_default_for_filled_array, default: [1]
serialize :serialized_array_with_no_defaults, Array
end
# ---
class BugTest < Minitest::Test
def test_the_version
assert PaperTrail.gem_version.is_a?(::Gem::Version)
assert_equal ::PaperTrail::VERSION::STRING, PaperTrail.gem_version.to_s
end
def test_non_paper_trailed_record_can_be_created_with_no_attributes
record = NonPaperTrailedRecord.create!
assert record
end
# ---
def test_paper_trailed_record_with_serialized_array_with_db_and_model_defaults_for_empty_array_can_be_created_with_no_attributes
record = PaperTrailedRecordOne.create!
assert record
# will raise ActiveRecord::SerializationTypeMismatch
end
def test_paper_trailed_record_with_serialized_array_with_db_default_for_empty_array_can_be_created_with_no_attributes
record = PaperTrailedRecordTwo.create!
assert record
end
def test_paper_trailed_record_with_serialized_array_with_model_default_for_empty_array_can_be_created_with_no_attributes
record = PaperTrailedRecordThree.create!
assert record
end
def test_paper_trailed_record_with_serialized_array_with_db_and_model_defaults_for_filled_array_can_be_created_with_no_attributes
record = PaperTrailedRecordFour.create!
assert record
# will raise ActiveRecord::SerializationTypeMismatch
end
def test_paper_trailed_record_with_serialized_array_with_db_default_for_filled_array_can_be_created_with_no_attributes
record = PaperTrailedRecordFive.create!
assert record
end
def test_paper_trailed_record_with_serialized_array_with_model_default_for_filled_array_can_be_created_with_no_attributes
record = PaperTrailedRecordSix.create!
assert record
end
def test_paper_trailed_record_with_serialized_array_with_no_defaults_can_be_created_with_no_attributes
record = PaperTrailedRecordSeven.create!
assert record
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment