paper_trail: Reify on associations fails if using Single Table Inheritance
It appears as though if Single Table Inheritance is being used on an association, if you try to reify with has_many: true or has_one: true, it will not find and build the previous version of the association and instead always use the current version of the association when browsing previous versions.
I believe this is happening because if STI is used, the item_type is always stored as the base class. But when calling the method reify_has_many_directly, it is using the main class of the association. This builds a WHERE clause that is looking for the wrong value in the item_type column.
ex:
class Document < ActiveRecord::Base
has_paper_trail
has_one :authorship
end
class Assignment < ActiveRecord::Base
belongs_to :document
end
class Authorship < Assignment
has_paper_trail
end
@document.reify(has_many: true, has_one: true)
The last line there will produce a SQL query like this:
SELECT `versions`.* FROM `versions`
INNER JOIN `version_associations` ON `version_associations`.`version_id` = `versions`.`id`
WHERE (version_associations.foreign_key_name = 'document_id')
AND (version_associations.foreign_key_id = 1)
AND (versions.item_type = 'Authorship')
AND (created_at >= '2015-08-26 20:07:28.000000' OR transaction_id = 933)
ORDER BY versions.id ASC LIMIT 1
But item_type will never be ‘Authorship’, it is always stored as Assignment. I’m still working on figuring out a solution to this if I can, but this seems to be what is happening from my understanding.
Modifying the database manually and changing the item_type column from Assignment to Authorship results in being able to view the correct versions of the association as I browse through the document history.
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 23 (18 by maintainers)
Commits related to this issue
- Docs: Limitations of STI support [Related to #594] [ci skip] — committed to paper-trail-gem/paper_trail by jaredbeck 8 years ago
- Docs: Limitations of STI support [Related to #594] [ci skip] — committed to devonestes/paper_trail by jaredbeck 8 years ago
- Docs: Limitations of STI support [Related to #594] [ci skip] — committed to devonestes/paper_trail by jaredbeck 8 years ago
- Fix for issue #594, reifying sub-classed models that use STI — committed to lorint/paper_trail by lorint 6 years ago
- Fix for issue #594, reifying sub-classed models that use STI — committed to lorint/paper_trail by lorint 6 years ago
- Fix for issue #594, reifying sub-classed models that use STI — committed to lorint/paper_trail by lorint 6 years ago
- Describe the fix for issue #594 — committed to lorint/paper_trail by lorint 6 years ago
- Fix for issue #594, reifying sub-classed models that use STI — committed to lorint/paper_trail by lorint 6 years ago
- Describe the fix for issue #594 — committed to lorint/paper_trail by lorint 6 years ago
- Fix for issue #594, reifying sub-classed models that use STI — committed to lorint/paper_trail by lorint 6 years ago
- Fix for issue #594, reifying sub-classed models that use STI (#1108) See the changes to the changelog and readme for details. — committed to paper-trail-gem/paper_trail by lorint 6 years ago
- Fix for issue #594, reifying sub-classed models that use STI (#1108) See the changes to the changelog and readme for details. — committed to aried3r/paper_trail by lorint 6 years ago
I worked with Kevin on this, your gist does reproduce the issue. Here’s another one too:
https://gist.github.com/daneshd/f0e61744075e1617dbcb
I was working on a fix for this issue but I haven’t had the time to finish it. One thing I noticed in your report is you’d like the
item_typeto be Authorship. I went down that path when patching paper_trail but it didn’t work out. I eventually found thisSaving
item_typeto the child model instead of the base model caused issues with how it was loaded.I tried to change the way the lookup was done to grab all the versions whose class is the base model here. I only started on the
reify_has_ones.This isn’t enough though. You could have more than 1 record saved with the base class if your model uses other
has_oneassociations of the same STI base model (e.g. thesponsorshipmodel in my bug report). Say I have a user that has an authorship and a sponsorship, then there would be 2 version records whose base class isAssignmentand whose foreign key is my user’s id.I tried iterating through the found versions to lookup and filter these by their
type. I wasn’t sure about this approach because I had to force PT to never skip/ignore thetypeattributes, and it meant serializing the object data to figure out which to use.Our implementation for versioning things caused some other issues for me so I had to put this fix on hold to figure that out. I never got around to
reify_has_manys.Thanks to André’s work in https://github.com/airblade/paper_trail/pull/1028 this issue is partially fixed and released as 8.1.2. Also thanks to André, we have a failing (skipped) test in
person_spec.rbthat should demonstrate the remaining issue.Danesh, have you done any more work on this since January? Is it still an issue with the latest version (currently 5.1.1)? Thanks.
https://github.com/airblade/paper_trail#5a-single-table-inheritance-sti now mentions this issue (#594) as a known issue.