Repository navigation
Reify on associations fails if using Single Table Inheritance #594
Description
Activity
Sounds like you're onto something. Thanks for the bug report.
I'm still working on figuring out a solution to this ..
Any luck? Even a failing test would be welcome, thanks.
Still working on this, Kevin? Were you able to write a failing test? Thanks.
Hey, sorry.
I'm still planning on looping back to take another look at this, just haven't had the time to get my head into the right space to try to sort this out again. I'll try to make it a priority soon and keep you updated!I recently adapted the AR bug report template for use in PaperTrail. Maybe it will help you write your failing test? Please check it out: https://github.com/airblade/paper_trail/blob/master/doc/bug_report_template.rb
I hope it helps!
Kevin, I think I've reproduced your issue: https://gist.github.com/jaredbeck/4664e45abe3aa09416ae
Does that look like the issue you're seeing?
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 thisUsing polymorphic associations in combination with single table inheritance (STI) is a little tricky. In order for the associations to work as expected, ensure that you store the base model for the STI models in the type column of the polymorphic association.
Saving
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.- where("#{version_table_name}.item_type = ?", assoc.class_name). + where("#{version_table_name}.item_type = ?", assoc.klass.base_class.name).
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.Reacted by Harry Whelchel and André Hester- added a commit that references this issue
on May 4, 2016 This just came up again recently. What do you think about ecd1df7 as a recommendation?
The STI related documentation from ecd1df7 looks good to me. Reifying the polymorphic associations are currently bugging out though. I think it may be better to say that it's a known issue instead. What do you think?
I think it may be better to say that it's a known issue instead.
https://github.com/airblade/paper_trail#5a-single-table-inheritance-sti now mentions this issue (#594) as a known issue.
Reacted by Danesh Dadachanji- added a commit that references this issue
on May 9, 2016 12 remaining items
@daneshd that is the only solution without adding a
item_sub_typecolumn filled if item is not a base class. This column would only be used for version lookup.@jaredbeck I need this feature working for versioning my models correctly as soon as possible. I found that changing the class name on reification to the base class name fixes my issue. I changed that and opened an PR. This will not fix the reification issues mentioned by @daneshd on having multiple
has_oneassociations on the same model pointing to a polymorphic model buthas_many_throughassociations to polymorphic models.Thanks to André's work in #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.Reacted by André HesterAlso thanks to André, we have a failing (skipped) test in person_spec.rb that should demonstrate the remaining issue.
Closed by 06a5e30 (will release in 9.0.0) which improves the message of the error raised. Because it's a very rare issue on an experimental feature, I don't intended to work on it further (thus, closing this) but PRs are welcome.
- added 4 commits that reference this issue
on Jun 5, 2018 - added a commit that references this issue
on Jul 30, 2018
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:
The last line there will produce a SQL query like this:
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.