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

Calling has_paper_trail on STI models causes 2 inserts to versions #1478

Open
3 tasks done
sobrinho opened this issue Jun 6, 2024 · 1 comment · May be fixed by #1479
Open
3 tasks done

Calling has_paper_trail on STI models causes 2 inserts to versions #1478

sobrinho opened this issue Jun 6, 2024 · 1 comment · May be fixed by #1479

Comments

@sobrinho
Copy link

sobrinho commented Jun 6, 2024

Thank you for your contribution!

Due to limited volunteers, issues that do not follow these instructions will be
closed without comment.

Check the following boxes:

  • 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

Due to limited volunteers, we cannot answer usage questions. Please ask such
questions on StackOverflow.

Bug reports must use the following template:

# frozen_string_literal: true

# Use this template to report PaperTrail bugs.
# Please include only the minimum code necessary to reproduce your issue.
require "bundler/inline"

# STEP ONE: What versions are you using?
gemfile(true) do
  ruby "3.3.0"
  source "https://rubygems.org"
  gem "activerecord"
  gem "minitest"
  gem "paper_trail", "12.1.0", require: false
  gem "sqlite3", "~> 1.4"
end

require "active_record"
require "minitest/autorun"
require "logger"

# Please use sqlite for your bug reports, if possible.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = nil
ActiveRecord::Schema.define do
  # STEP TWO: Define your tables here.
  create_table :users, force: true do |t|
    t.string :type
    t.text :first_name, null: false
    t.timestamps null: false
  end

  create_table :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
  add_index :versions, %i[item_type item_id]
end
ActiveRecord::Base.logger = Logger.new(STDOUT)
require "paper_trail"

# STEP FOUR: Define your AR models here.
class User < ActiveRecord::Base
  has_paper_trail
end

class Admin < User
  has_paper_trail on: [:create]
end

# STEP FIVE: Please write a test that demonstrates your issue.
class BugTest < ActiveSupport::TestCase
  def test_1
    assert_difference(-> { PaperTrail::Version.count }, +1) {
      User.create(first_name: "Jane")
    }
  end

  def test_2
    assert_difference(-> { PaperTrail::Version.count }, +1) {
      Admin.create(first_name: "Jane")
    }
  end
end

# STEP SIX: Run this script using `ruby my_bug_report.rb`

Our real scenario is actually like this:

class ApplicationRecord < ActiveRecord::Base
  NON_PAPER_TRAIL_MODELS = %w[
    X
    Y
    Z
  ]

  def self.inherited(other)
    super

    other.has_paper_trail unless NON_PAPER_TRAIL_MODELS.include? other.name
  end
end

When the root class is created class MyModel < ApplicationRecord, it calls has_paper_trail and when class MyOtherModel < MyModel is created, it calls it again.

Current workaround:

  def self.inherited(other)
    super

    other.has_paper_trail unless other.respond_to?(:paper_trail_options) || NON_PAPER_TRAIL_MODELS.include?(other.name)
  end

I would expect the gem to raise an error if that's not allowed or simple ignore the call if nothing has changed, or even better, respect the options for the STI models in the case it is different from the root model.

@fatkodima
Copy link
Contributor

Opened a PR to address this.

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

Successfully merging a pull request may close this issue.

2 participants