Fix item_type in association reification query (#996)

When a record is inserted into the `versions` table, it is given an `item_type` like `Foo::Bar`, but the association reification queries were searching for an `item_type` like `::Foo::Bar`.
This commit is contained in:
chimame 2017-10-05 11:02:46 +09:00 committed by Jared Beck
parent ac96b70dbe
commit 56991ae9a1
10 changed files with 170 additions and 5 deletions

View File

@ -19,7 +19,8 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).
### Fixed
- None
- Fix Associations
supports revision of association with module name.
## 7.1.3 (2017-09-19)

View File

@ -37,7 +37,7 @@ module PaperTrail
# @api private
def load_version(assoc, id, transaction_id, version_at)
assoc.klass.paper_trail.version_class.
where("item_type = ?", assoc.class_name).
where("item_type = ?", assoc.klass.name).
where("item_id = ?", id).
where("created_at >= ? OR transaction_id = ?", version_at, transaction_id).
order("id").limit(1).first

View File

@ -98,7 +98,7 @@ module PaperTrail
select("MIN(version_id)").
where("foreign_key_name = ?", assoc.foreign_key).
where("foreign_key_id = ?", model.id).
where("#{version_table}.item_type = ?", assoc.class_name).
where("#{version_table}.item_type = ?", assoc.klass.name).
where("created_at >= ? OR transaction_id = ?", version_at, tx_id).
group("item_id").
to_sql

View File

@ -73,7 +73,7 @@ module PaperTrail
def load_versions_for_hmt_association(assoc, ids, tx_id, version_at)
version_id_subquery = assoc.klass.paper_trail.version_class.
select("MIN(id)").
where("item_type = ?", assoc.class_name).
where("item_type = ?", assoc.klass.name).
where("item_id IN (?)", ids).
where(
"created_at >= ? OR transaction_id = ?",

View File

@ -36,7 +36,7 @@ module PaperTrail
model.class.paper_trail.version_class.joins(:version_associations).
where("version_associations.foreign_key_name = ?", assoc.foreign_key).
where("version_associations.foreign_key_id = ?", model.id).
where("#{version_table_name}.item_type = ?", assoc.class_name).
where("#{version_table_name}.item_type = ?", assoc.klass.name).
where("created_at >= ? OR transaction_id = ?", version_at, transaction_id).
order("#{version_table_name}.id ASC").
first

View File

@ -0,0 +1,23 @@
module Family
class Family < ActiveRecord::Base
has_paper_trail
has_many :familie_lines, class_name: "::Family::FamilyLine", foreign_key: :parent_id
has_many :children, class_name: "::Family::Family", foreign_key: :parent_id
has_many :grandsons, through: :familie_lines
has_one :mentee, class_name: "::Family::Family", foreign_key: :partner_id
if ActiveRecord.gem_version >= Gem::Version.new("5.0")
belongs_to :parent, class_name: "::Family::Family", foreign_key: :parent_id, optional: true
else
belongs_to :parent, class_name: "::Family::Family", foreign_key: :parent_id
end
if ActiveRecord.gem_version >= Gem::Version.new("5.0")
belongs_to :mentor, class_name: "::Family::Family", foreign_key: :partner_id, optional: true
else
belongs_to :mentor, class_name: "::Family::Family", foreign_key: :partner_id
end
accepts_nested_attributes_for :mentee
accepts_nested_attributes_for :children
end
end

View File

@ -0,0 +1,19 @@
module Family
class FamilyLine < ActiveRecord::Base
has_paper_trail
if ActiveRecord.gem_version >= Gem::Version.new("5.0")
belongs_to :parent, class_name: "::Family::Family", foreign_key: :parent_id, optional: true
else
belongs_to :parent, class_name: "::Family::Family", foreign_key: :parent_id
end
if ActiveRecord.gem_version >= Gem::Version.new("5.0")
belongs_to :grandson, class_name: "::Family::Family",
foreign_key: :grandson_id,
optional: true
else
belongs_to :grandson, class_name: "::Family::Family",
foreign_key: :grandson_id
end
end
end

View File

@ -315,6 +315,17 @@ class SetUpTestTables < (
t.datetime :created_at
end
add_index :custom_primary_key_record_versions, %i[item_type item_id], name: "idx_cust_pk_item"
create_table :family_lines do |t|
t.integer :parent_id
t.integer :grandson_id
end
create_table :families do |t|
t.string :name
t.integer :parent_id
t.integer :partner_id
end
end
def down

View File

@ -111,6 +111,17 @@ ActiveRecord::Schema.define(version: 20110208155312) do
t.integer "editor_id"
end
create_table "families", force: :cascade do |t|
t.string "name"
t.integer "parent_id"
t.integer "partner_id"
end
create_table "family_lines", force: :cascade do |t|
t.integer "parent_id"
t.integer "grandson_id"
end
create_table "fluxors", force: :cascade do |t|
t.integer "widget_id"
t.string "name"

View File

@ -122,6 +122,31 @@ RSpec.describe(::PaperTrail, versioning: true) do
end
end
end
context "module name is given" do
let(:parent_with_partner) do
parent = Family::Family.new(name: "parent1")
parent.build_mentee(name: "partner1")
parent.save!
Timecop.travel(1.second.since)
parent
end
context "change partner" do
before do
parent_with_partner.update_attributes(
name: "parent2",
mentee_attributes: { id: parent_with_partner.mentee.id, name: "partner2" }
)
end
it "reify partner" do
previous_parent = parent_with_partner.versions.last.reify(has_one: true)
previous_partner = previous_parent.mentee
expect(previous_partner.name).to eq "partner1"
end
end
end
end
context "a has_many association" do
@ -284,6 +309,31 @@ RSpec.describe(::PaperTrail, versioning: true) do
end
end
end
context "module name is given" do
let(:parent_with_children) do
parent = Family::Family.new(name: "parent1")
parent.children.build(name: "child1")
parent.save!
Timecop.travel(1.second.since)
parent
end
context "create new children" do
before do
parent_with_children.name = "parent2"
parent_with_children.children.build(name: "child2")
parent_with_children.save!
end
it "reify children" do
previous_parent = parent_with_children.versions.last.reify(has_many: true)
previous_children = previous_parent.children
expect(previous_children.size).to eq 1
expect(previous_children.first.name).to eq "child1"
end
end
end
end
context "has_many through associations" do
@ -701,6 +751,31 @@ RSpec.describe(::PaperTrail, versioning: true) do
end
end
end
context "module name is given" do
let(:parent_with_grandsons) do
parent = Family::Family.new(name: "parent1")
parent.grandsons.build(name: "grandson1")
parent.save!
Timecop.travel(1.second.since)
parent
end
context "create new grandsons" do
before do
parent_with_grandsons.name = "parent2"
parent_with_grandsons.grandsons.build(name: "grandson2")
parent_with_grandsons.save!
end
it "reify grandsons" do
previous_parent = parent_with_grandsons.versions.last.reify(has_many: true)
previous_grandsons = previous_parent.grandsons
expect(previous_grandsons.size).to eq 1
expect(previous_grandsons.first.name).to eq "grandson1"
end
end
end
end
context "belongs_to associations" do
@ -835,6 +910,31 @@ RSpec.describe(::PaperTrail, versioning: true) do
end
end
end
context "module name is given" do
let(:parent_with_children) do
parent = Family::Family.new(name: "parent1")
parent.children.build(name: "child1")
parent.save!
Timecop.travel(1.second.since)
parent
end
context "change children" do
before do
parent_with_children.update_attributes!(
name: "parent2",
children_attributes: { id: parent_with_children.children.first.id, name: "child2" }
)
end
it "reify parent" do
previous_children = parent_with_children.children.
first.versions.last.reify(belongs_to: true)
expect(previous_children.parent.name).to eq "parent1"
end
end
end
end
context "has_and_belongs_to_many associations" do