Skip to content

versions raises error whenever PaperTrail::Version is a parent to an abstract superclass #1464

Closed as not planned
@searls

Description

@searls
  • 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions