MONGOID-5790 MONGOID-5791 Fix error caused by loading a referenced class prematurely #5839
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The problem manifested when a class declared an association on a class that hadn't yet been loaded; when the touchable module began adding its functionality, there were a few lines that tried to load the referenced class, e.g.:
This would result in a
NameError
because theembedded_in
association could not find theParent
class at load-time.I started by checking to see if we could just raise a more informative error in this case, as a stop-gap before spending more time later to actually fix the issue. Imagine my joy when I realized that the entire problem was caused by a few lines of dead-code! By simply deleting the unused code, the problem went away. 🎉
Edit: a bit more explanation here, after I went through and triple checked the logic. An
Association
has aklass
, which is the class that the association references directly. In the above example, theChild#parent
association would haveParent
as theklass
. AnAssociation
also has aninverse_class
, which is the class that the association belongs to. Again, to use theChild#parent
association as an example, this would be theChild
class.The reason everything "just works", even when the
klass
references haven't yet been defined, is because the touch behaviors are added to theinverse_class
, and not theklass
. That is to say, when theMongoid::Touchable
model works its magic in anembedded_in
association, it adds the new methods toChild
, and notParent
. Ditto for any of the other associations. Thus, it doesn't matter (at load time) whether theklass
references exist yet or not, because all we care about are theinverse_class
references, which are guaranteed to exist.