Description
- This is not a usage question, this is a bug report
- This bug can be reproduced with the script I provide below
- This bug can be reproduced in the latest release of the
paper_trail
gem
This is the exact same issue demonstrated 7 years ago on StackOverflow. In short, extending from PaperTrail::Version in an abstract class and then extending that abstract class to a concrete custom version model class will raise an error whenever #versions
is called
Reproduction script
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
ruby "~> 3.3.0"
gem "activerecord", "~> 7.1.3"
gem "minitest", "~> 5.21.2"
gem "paper_trail", "~> 15.1.0"
gem "sqlite3", "~> 1.7.2"
end
require "active_record"
require "minitest/autorun"
require "logger"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = nil
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.text :first_name, null: false
t.timestamps
end
create_table :user_versions do |t|
t.string :item_type, null: false
t.integer :item_id, null: false
t.string :event, null: false
t.string :whodunnit
t.text :object, limit: 1_073_741_823
t.text :object_changes, limit: 1_073_741_823
t.datetime :created_at
end
end
ActiveRecord::Base.logger = Logger.new($stdout)
require "paper_trail"
class ApplicationVersion < PaperTrail::Version
self.abstract_class = true
end
class UserVersion < ApplicationVersion
self.table_name = :user_versions
end
class User < ActiveRecord::Base
has_paper_trail versions: {
class_name: "UserVersion"
}
end
class ExtendingPaperTrailVersionWithCustomTable < ActiveSupport::TestCase
def test_custom_table_fails
user = User.create!(first_name: "Jane")
user.versions
end
end
This will fail with error:
1) Error:
ExtendingPaperTrailVersionWithCustomTable#test_custom_table_fails:
ActiveRecord::StatementInvalid: Could not find table 'versions'
And anyone finding this via Google, this is the error you'll see in Postgres as opposed to sqlite:
PG::UndefinedTable: ERROR: relation "versions" does not exist (ActiveRecord::StatementInvalid)
LINE 10: WHERE a.attrelid = '"versions"'::regclass
Workaround
Changing ApplicationVersion
to instead extend from ActiveRecord::Base
and include PaperTrail::VersionConcern
works, however:
class ApplicationVersion < ActiveRecord::Base
include PaperTrail::VersionConcern
self.abstract_class = true
end
Another workaround would be to eliminate the grandparent and have one's custom version classes extend directly from PaperTrail::Version
. This also works:
class UserVersion < PaperTrail::Version
self.table_name = :user_versions
end
Why did I do this to myself?
This example from the readme—ironically, about custom version class names—extends from PaperTrail::Version
instead of including the concern
class UserVersion < PaperTrail::Version
self.table_name = :user_versions
belongs_to :user, foreign_key: :item_id
end
Since I wanted to own a custom ApplicationVersion
from which all my custom versions could extend, I fell into this trap