Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
3 tasks done
searls opened this issue Feb 27, 2024 · 0 comments
Open
3 tasks done

Comments

@searls
Copy link

searls commented Feb 27, 2024

  • 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant