mirror of
https://github.com/paper-trail-gem/paper_trail.git
synced 2022-11-09 11:33:19 -05:00
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:
parent
ac96b70dbe
commit
56991ae9a1
10 changed files with 170 additions and 5 deletions
|
@ -19,7 +19,8 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- None
|
- Fix Associations
|
||||||
|
supports revision of association with module name.
|
||||||
|
|
||||||
## 7.1.3 (2017-09-19)
|
## 7.1.3 (2017-09-19)
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ module PaperTrail
|
||||||
# @api private
|
# @api private
|
||||||
def load_version(assoc, id, transaction_id, version_at)
|
def load_version(assoc, id, transaction_id, version_at)
|
||||||
assoc.klass.paper_trail.version_class.
|
assoc.klass.paper_trail.version_class.
|
||||||
where("item_type = ?", assoc.class_name).
|
where("item_type = ?", assoc.klass.name).
|
||||||
where("item_id = ?", id).
|
where("item_id = ?", id).
|
||||||
where("created_at >= ? OR transaction_id = ?", version_at, transaction_id).
|
where("created_at >= ? OR transaction_id = ?", version_at, transaction_id).
|
||||||
order("id").limit(1).first
|
order("id").limit(1).first
|
||||||
|
|
|
@ -98,7 +98,7 @@ module PaperTrail
|
||||||
select("MIN(version_id)").
|
select("MIN(version_id)").
|
||||||
where("foreign_key_name = ?", assoc.foreign_key).
|
where("foreign_key_name = ?", assoc.foreign_key).
|
||||||
where("foreign_key_id = ?", model.id).
|
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).
|
where("created_at >= ? OR transaction_id = ?", version_at, tx_id).
|
||||||
group("item_id").
|
group("item_id").
|
||||||
to_sql
|
to_sql
|
||||||
|
|
|
@ -73,7 +73,7 @@ module PaperTrail
|
||||||
def load_versions_for_hmt_association(assoc, ids, tx_id, version_at)
|
def load_versions_for_hmt_association(assoc, ids, tx_id, version_at)
|
||||||
version_id_subquery = assoc.klass.paper_trail.version_class.
|
version_id_subquery = assoc.klass.paper_trail.version_class.
|
||||||
select("MIN(id)").
|
select("MIN(id)").
|
||||||
where("item_type = ?", assoc.class_name).
|
where("item_type = ?", assoc.klass.name).
|
||||||
where("item_id IN (?)", ids).
|
where("item_id IN (?)", ids).
|
||||||
where(
|
where(
|
||||||
"created_at >= ? OR transaction_id = ?",
|
"created_at >= ? OR transaction_id = ?",
|
||||||
|
|
|
@ -36,7 +36,7 @@ module PaperTrail
|
||||||
model.class.paper_trail.version_class.joins(:version_associations).
|
model.class.paper_trail.version_class.joins(:version_associations).
|
||||||
where("version_associations.foreign_key_name = ?", assoc.foreign_key).
|
where("version_associations.foreign_key_name = ?", assoc.foreign_key).
|
||||||
where("version_associations.foreign_key_id = ?", model.id).
|
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).
|
where("created_at >= ? OR transaction_id = ?", version_at, transaction_id).
|
||||||
order("#{version_table_name}.id ASC").
|
order("#{version_table_name}.id ASC").
|
||||||
first
|
first
|
||||||
|
|
23
spec/dummy_app/app/models/family/family.rb
Normal file
23
spec/dummy_app/app/models/family/family.rb
Normal 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
|
19
spec/dummy_app/app/models/family/family_line.rb
Normal file
19
spec/dummy_app/app/models/family/family_line.rb
Normal 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
|
|
@ -315,6 +315,17 @@ class SetUpTestTables < (
|
||||||
t.datetime :created_at
|
t.datetime :created_at
|
||||||
end
|
end
|
||||||
add_index :custom_primary_key_record_versions, %i[item_type item_id], name: "idx_cust_pk_item"
|
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
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
|
|
|
@ -111,6 +111,17 @@ ActiveRecord::Schema.define(version: 20110208155312) do
|
||||||
t.integer "editor_id"
|
t.integer "editor_id"
|
||||||
end
|
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|
|
create_table "fluxors", force: :cascade do |t|
|
||||||
t.integer "widget_id"
|
t.integer "widget_id"
|
||||||
t.string "name"
|
t.string "name"
|
||||||
|
|
|
@ -122,6 +122,31 @@ RSpec.describe(::PaperTrail, versioning: true) do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context "a has_many association" do
|
context "a has_many association" do
|
||||||
|
@ -284,6 +309,31 @@ RSpec.describe(::PaperTrail, versioning: true) do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context "has_many through associations" do
|
context "has_many through associations" do
|
||||||
|
@ -701,6 +751,31 @@ RSpec.describe(::PaperTrail, versioning: true) do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context "belongs_to associations" do
|
context "belongs_to associations" do
|
||||||
|
@ -835,6 +910,31 @@ RSpec.describe(::PaperTrail, versioning: true) do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context "has_and_belongs_to_many associations" do
|
context "has_and_belongs_to_many associations" do
|
||||||
|
|
Loading…
Reference in a new issue