diff --git a/lib/paper_trail/events/base.rb b/lib/paper_trail/events/base.rb index d4692d5a7..7483b56a9 100644 --- a/lib/paper_trail/events/base.rb +++ b/lib/paper_trail/events/base.rb @@ -162,6 +162,15 @@ def ignored_attr_has_changed? ignored.any? && (changed_in_latest_version & ignored).any? end + # PT 10 has a new optional column, `item_subtype` + # + # @api private + def merge_item_subtype_into(data) + if @record.class.paper_trail.version_class.columns_hash.key?("item_subtype") + data.merge!(item_subtype: @record.class.name) + end + end + # Updates `data` from the model's `meta` option and from `controller_info`. # Metadata is always recorded; that means all three events (create, update, # destroy) and `update_columns`. diff --git a/lib/paper_trail/events/create.rb b/lib/paper_trail/events/create.rb index 76c014b42..a04adda68 100644 --- a/lib/paper_trail/events/create.rb +++ b/lib/paper_trail/events/create.rb @@ -23,6 +23,7 @@ def data changes = notable_changes data[:object_changes] = prepare_object_changes(changes) end + merge_item_subtype_into(data) merge_metadata_into(data) end end diff --git a/lib/paper_trail/events/destroy.rb b/lib/paper_trail/events/destroy.rb index 33786c0d8..52ea401c7 100644 --- a/lib/paper_trail/events/destroy.rb +++ b/lib/paper_trail/events/destroy.rb @@ -26,6 +26,7 @@ def data changes = @record.attributes.map { |attr, value| [attr, [value, nil]] }.to_h data[:object_changes] = prepare_object_changes(changes) end + merge_item_subtype_into(data) merge_metadata_into(data) end end diff --git a/lib/paper_trail/events/update.rb b/lib/paper_trail/events/update.rb index c2b59b6b7..01b3ecf3d 100644 --- a/lib/paper_trail/events/update.rb +++ b/lib/paper_trail/events/update.rb @@ -38,6 +38,7 @@ def data changes = @force_changes.nil? ? notable_changes : @force_changes data[:object_changes] = prepare_object_changes(changes) end + merge_item_subtype_into(data) merge_metadata_into(data) end diff --git a/spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb b/spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb index d102aa90a..154de4756 100644 --- a/spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb +++ b/spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb @@ -78,9 +78,10 @@ def up end create_table :versions, versions_table_options do |t| - t.string :item_type, item_type_options - t.integer :item_id, null: false - t.string :event, null: false + t.string :item_type, item_type_options(null: false) + t.integer :item_id, null: false + t.string :item_subtype, item_type_options(null: true) + t.string :event, null: false t.string :whodunnit t.text :object, limit: TEXT_BYTES t.text :object_changes, limit: TEXT_BYTES @@ -377,8 +378,8 @@ def down private - def item_type_options - opt = { null: false } + def item_type_options(null:) + opt = { null: null } opt[:limit] = 191 if mysql? opt end diff --git a/spec/models/family/celebrity_family_spec.rb b/spec/models/family/celebrity_family_spec.rb index 430f87563..2d12c9b7a 100644 --- a/spec/models/family/celebrity_family_spec.rb +++ b/spec/models/family/celebrity_family_spec.rb @@ -3,23 +3,22 @@ require "spec_helper" module Family - RSpec.describe CelebrityFamily, type: :model, skip: true, versioning: true do + RSpec.describe CelebrityFamily, type: :model, versioning: true do describe "#create" do - # https://github.com/paper-trail-gem/paper_trail/pull/1108 - it "creates a version record with item_type == class.name, not base_class" do + it "creates version with item_subtype == class.name, not base_class" do carter = described_class.create( name: "Carter", path_to_stardom: "Mexican radio" ) v = carter.versions.last expect(v[:event]).to eq("create") - expect(v[:item_type]).to eq("Family::CelebrityFamily") + expect(v[:item_subtype]).to eq("Family::CelebrityFamily") end end describe "#reify" do context "belongs_to" do - it "uses the correct item_type in queries" do + it "uses the correct item_subtype" do parent = described_class.new(name: "Jermaine Jackson") parent.path_to_stardom = "Emulating Motown greats such as the Temptations and "\ "The Supremes" @@ -30,12 +29,13 @@ module Family name: "Hazel Gordy", children_attributes: { id: child1.id, name: "Jay Jackson" } ) - # We expect `reify` for all versions to have item_type 'Family::CelebrityFamily', - # not 'Family::Family'. See PR #1108 + expect(parent.versions.count).to eq(2) # A create and an update parent.versions.each do |parent_version| - expect(parent_version.item_type).to eq(parent.class.name) + expect(parent_version.item_type).to eq("Family::Family") + expect(parent_version.item_subtype).to eq("Family::CelebrityFamily") end + expect(parent.versions[1].reify).to be_a(::Family::CelebrityFamily) end end @@ -50,11 +50,10 @@ module Family parent.children.build(name: "Pugsley") parent.save! - # We expect `reify` for all versions to have item_type 'Family::CelebrityFamily', - # not 'Family::Family'. See PR #1108 expect(parent.versions.count).to eq(2) parent.versions.each do |parent_version| - expect(parent_version.item_type).to eq(parent.class.name) + expect(parent_version.item_type).to eq("Family::Family") + expect(parent_version.item_subtype).to eq("Family::CelebrityFamily") end end end @@ -71,11 +70,10 @@ module Family parent.grandsons.build(name: "Rodney") parent.save! - # We expect `reify` for all versions to have item_type 'Family::CelebrityFamily', - # not 'Family::Family'. See PR #1108 expect(parent.versions.count).to eq(2) parent.versions.each do |parent_version| - expect(parent_version.item_type).to eq(parent.class.name) + expect(parent_version.item_type).to eq("Family::Family") + expect(parent_version.item_subtype).to eq("Family::CelebrityFamily") end end end @@ -93,19 +91,17 @@ module Family mentee_attributes: { id: parent.mentee.id, name: "Al Shean" } ) - # We expect `reify` for all versions to have item_type 'Family::CelebrityFamily', - # not 'Family::Family'. See PR #1108 expect(parent.versions.count).to eq(2) parent.versions.each do |parent_version| - expect(parent_version.item_type).to eq(parent.class.name) + expect(parent_version.item_type).to eq("Family::Family") + expect(parent_version.item_subtype).to eq("Family::CelebrityFamily") end end end end describe "#update" do - # https://github.com/paper-trail-gem/paper_trail/pull/1108 - it "creates a version record with item_type == class.name, not base_class" do + it "creates version with item_subtype == class.name, not base_class" do carter = described_class.create( name: "Carter", path_to_stardom: "Mexican radio" @@ -113,7 +109,8 @@ module Family carter.update(path_to_stardom: "Johnny") v = carter.versions.last expect(v[:event]).to eq("update") - expect(v[:item_type]).to eq("Family::CelebrityFamily") + expect(v[:item_type]).to eq("Family::Family") + expect(v[:item_subtype]).to eq("Family::CelebrityFamily") end end end diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb index b7dd6870d..0ac641690 100644 --- a/spec/models/person_spec.rb +++ b/spec/models/person_spec.rb @@ -166,7 +166,7 @@ expect(person.reload.versions.length).to(eq(3)) - # These will work when PT-AT has PR #5 merged: + # These will work when PT-AT adds support for the new `item_subtype` column # second_version = person.reload.versions.second.reify(has_one: true) # expect(second_version.car.name).to(eq("BMW 325")) # expect(second_version.bicycle.name).to(eq("BMX 1.0")) diff --git a/spec/paper_trail/events/destroy_spec.rb b/spec/paper_trail/events/destroy_spec.rb index 75abee5ea..fd89ed0ed 100644 --- a/spec/paper_trail/events/destroy_spec.rb +++ b/spec/paper_trail/events/destroy_spec.rb @@ -5,15 +5,15 @@ module PaperTrail module Events ::RSpec.describe Destroy do - describe "#data", skip: true, versioning: true do - # https://github.com/paper-trail-gem/paper_trail/pull/1108 - it "uses class.name for item_type, not base_class" do + describe "#data", versioning: true do + it "includes correct item_subtype" do carter = Family::CelebrityFamily.new( name: "Carter", path_to_stardom: "Mexican radio" ) data = PaperTrail::Events::Destroy.new(carter, true).data - expect(data[:item_type]).to eq("Family::CelebrityFamily") + expect(data[:item_type]).to eq("Family::Family") + expect(data[:item_subtype]).to eq("Family::CelebrityFamily") end end end