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

Fix get version data with full name of class #996

Merged

Conversation

chimame
Copy link
Contributor

@chimame chimame commented Sep 20, 2017

Overview

Unable to acquire association history of model name including module name.

Impact point

It can be reproduced in the following cases.

class Family::Person < ApplicationRecord
  has_paper_trail

  has_many :children
end

class Family::Child < ApplicationRecord
  has_paper_trail

  belongs_to :person
end

person = Family::Person.new(name: 'person1')
person.children.build(name: 'child1')
person.save #=> create versions. 1 is person1, 2 is child1

person.name = 'person2'
person.children.build(name: 'child2')
person.save #=> create versions. 3 is person2, 4 is child2

version = PaperTrail::Version.find(3) #=> version of person
person_history = version.reify(has_many: true)
person_history.children #=> Get current child1 and child2. Correctly, it is to get history of child1.

This happens because item_type does not include the module name when acquiring an association.

SELECT
  "versions".*
FROM
  "versions"
WHERE (id IN (
  SELECT
    MIN(version_id)
  FROM
    "version_associations"
  INNER JOIN
    "versions"
  ON
    "versions"."id" = "version_associations"."version_id"
  WHERE
    (foreign_key_name = 'person_id') AND
    (foreign_key_id = 1) AND
    (versions.item_type = 'Child') AND -- <= It does not include module name
    (created_at >= '2017-09-20 12:20:26.080113' OR transaction_id = 4)
  GROUP BY item_id))

@jaredbeck
Copy link
Member

Hi @chimame, thanks for the contribution!

Please include:

  1. a test (maybe in spec/paper_trail/associations_spec.rb or in spec/models)
  2. a changelog entry under Unreleased -> Fixed

Thanks!

Copy link
Member

@jaredbeck jaredbeck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes requested

@chimame chimame force-pushed the fix_association_can_not_be_loaded branch 4 times, most recently from ad06cc2 to ebe3766 Compare September 22, 2017 15:36
@chimame chimame force-pushed the fix_association_can_not_be_loaded branch from ebe3766 to 3f714e7 Compare September 22, 2017 15:46
@jaredbeck jaredbeck dismissed their stale review September 22, 2017 17:48

Needs second review

@jaredbeck
Copy link
Member

It would be great if we could do a test without introducing any new AR models; we already have so many.

@chimame
Copy link
Contributor Author

chimame commented Sep 23, 2017

Hi @jaredbeck, Thank you for reviewing.

What's going on?

Do you mean that we want you to create a test without creating a new AR?
If so, does it make sense to create a test using Kitchen::Banana?

@jaredbeck
Copy link
Member

It would be great if we could do a test without introducing any new AR models; we already have so many.

Do you mean that we want you to create a test without creating a new AR?

Yes. Currently this PR adds five new tables to the test suite. Please add fewer tables, if possible. Thanks!

@jaredbeck
Copy link
Member

Let me know if you need help with getting the tests to pass.

@chimame
Copy link
Contributor Author

chimame commented Sep 26, 2017

Thank you for following me.
I am planning to deal with less generation of models.

@chimame
Copy link
Contributor Author

chimame commented Sep 28, 2017

Please review once again.

Copy link
Member

@jaredbeck jaredbeck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, thanks! Only one minor change: "mentor" instead of "menter".

module Family
def self.table_name_prefix
"family_"
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat! I didn't know about this method. I will be able to use this at work.

expect(previous_children.parent.name).to eq "parent1"
end
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for testing all four association types.

belongs_to :parent, class_name: "Family::Person", foreign_key: :parent_id
end
if ActiveRecord.gem_version >= Gem::Version.new("5.0")
belongs_to :menter, class_name: "Family::Person", foreign_key: :partner_id, optional: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Mentor" is the correct spelling. English is silly.

@jaredbeck
Copy link
Member

Actually, I think we can delete the menter association, because it is not used anywhere?

@jaredbeck
Copy link
Member

Hmmm ... bad news. I can apply the following patch and all tests pass, including your new tests.

diff --git a/lib/paper_trail/reifiers/belongs_to.rb b/lib/paper_trail/reifiers/belongs_to.rb
index 483f791..3ff54b8 100644
--- a/lib/paper_trail/reifiers/belongs_to.rb
+++ b/lib/paper_trail/reifiers/belongs_to.rb
@@ -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.klass.name).
+            where("item_type = ?", assoc.class_name).
             where("item_id = ?", id).
             where("created_at >= ? OR transaction_id = ?", version_at, transaction_id).
             order("id").limit(1).first
diff --git a/lib/paper_trail/reifiers/has_many.rb b/lib/paper_trail/reifiers/has_many.rb
index 2c1c2c7..486acb2 100644
--- a/lib/paper_trail/reifiers/has_many.rb
+++ b/lib/paper_trail/reifiers/has_many.rb
@@ -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.klass.name).
+            where("#{version_table}.item_type = ?", assoc.class_name).
             where("created_at >= ? OR transaction_id = ?", version_at, tx_id).
             group("item_id").
             to_sql
diff --git a/lib/paper_trail/reifiers/has_many_through.rb b/lib/paper_trail/reifiers/has_many_through.rb
index af24206..fac4ef9 100644
--- a/lib/paper_trail/reifiers/has_many_through.rb
+++ b/lib/paper_trail/reifiers/has_many_through.rb
@@ -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.klass.name).
+            where("item_type = ?", assoc.class_name).
             where("item_id IN (?)", ids).
             where(
               "created_at >= ? OR transaction_id = ?",
diff --git a/lib/paper_trail/reifiers/has_one.rb b/lib/paper_trail/reifiers/has_one.rb
index 85b96b7..ad66112 100644
--- a/lib/paper_trail/reifiers/has_one.rb
+++ b/lib/paper_trail/reifiers/has_one.rb
@@ -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.klass.name).
+            where("#{version_table_name}.item_type = ?", assoc.class_name).
             where("created_at >= ? OR transaction_id = ?", version_at, transaction_id).
             order("#{version_table_name}.id ASC").
             first

Assuming I'm running the test suite correctly, this means that your new tests do not actually demonstrate a problem.

What am I missing?

@chimame
Copy link
Contributor Author

chimame commented Oct 1, 2017

I'm sorry.
The bug reported by me does not seem to occur when I give table name prefix.
So, I changed it to not give it.

Actually, I think we can delete the menter association, because it is not used anywhere?

It can not be deleted.
Because we need to define "belongs_to" when creating version associations.

@jaredbeck
Copy link
Member

The directory name models/Family does not match the file naming conventions for ruby. Please avoid using upper case letters in file names.

@jaredbeck
Copy link
Member

I'm sorry. The bug reported by me does not seem to occur when I give table name prefix. So, I changed it to not give it.

I want the tests to fail when I apply this patch. Are you ready for me to perform that experiment? Thanks!

@chimame
Copy link
Contributor Author

chimame commented Oct 4, 2017

The test will fail if the specified patch is applied. please make sure.
Thank you!

@jaredbeck
Copy link
Member

The test will fail if the specified patch is applied. please make sure.

When I apply the patch, the tests fail. Thanks!

@jaredbeck jaredbeck merged commit 56991ae into paper-trail-gem:master Oct 5, 2017
@jaredbeck
Copy link
Member

Released as 8.0.0.

jaredbeck added a commit that referenced this pull request Oct 5, 2017
I avoid using `let` and `before` unless necessary.
@chimame chimame deleted the fix_association_can_not_be_loaded branch October 5, 2017 13:02
aried3r pushed a commit to aried3r/paper_trail that referenced this pull request Dec 14, 2020
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`.
aried3r pushed a commit to aried3r/paper_trail that referenced this pull request Dec 14, 2020
I avoid using `let` and `before` unless necessary.
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 this pull request may close these issues.

2 participants