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

Change DescendantLoader to handle non-AR classes in the models directory #16867

Merged

Conversation

Fryguy
Copy link
Member

@Fryguy Fryguy commented Jan 23, 2018

Class is patched by ActiveSupport to add the descendants method, so this change
keeps our patching of ActiveSupport consistent across the board by also patching
Class. This was handled specifically for ActsAsArModel previously, but there
are other classes that also might need this functionality such as Authenticator.
Individually adding new classes is not maintainable and also not expected, so
this is handled generically via a patch to Class.

We still need to keep our ActiveRecord::Base patch because due to timing. By
the time we hit the patching lines, ActiveRecord::Base has already been further
modified with ActiveSupport::DescendantsTracker via prepend, and if we were to
rely on the Class patch, then we wouldn't be able to get ahead of
DescendantsTracker.

Visually, the singleton_class' ancestors chain looks like this for Object:

[
  #<Class:Object>,
  ...
  DescendantLoader::ArDescendantsWithLoader,
  Class,
  ...
  Object,
  ...
]

but looks like this for ActiveRecord::Base (if we were to rely on the
Class patch only):

[
  #<Class:ActiveRecord::Base>,
  ...
  ActiveSupport::DescendantsTracker,
  ...
  #<Class:Object>,
  ...
  DescendantLoader::ArDescendantsWithLoader,
  Class,
  ...
  Object,
  ...
]

Thus ActiveSupport::DescendantsTracker's definition of descedants wins, unless
we patch ActiveRecord::Base directly.

https://bugzilla.redhat.com/show_bug.cgi?id=1537299

Paired on this with @jvlcek and @bdunne
@jrafanie Please review.

Class is patched by ActiveSupport to add the descendants method, so this change
keeps our patching of ActiveSupport consistent across the board by also patching
Class.  This was handled specifically for ActsAsArModel previously, but there
are other classes that also might need this functionality such as Authenticator.
Individually adding new classes is not maintainable and also not expected, so
this is handled generically via a patch to Class.

We still need to keep our ActiveRecord::Base patch because due to timing.  By
the time we hit the patching lines, ActiveRecord::Base has already been further
modified with ActiveSupport::DescendantsTracker via prepend, and if we were to
rely on the Class patch, then we wouldn't be able to get ahead of
DescendantsTracker.

Visually, the singleton_class' ancestors chain looks like this for Object:

    [
      #<Class:Object>,
      ...
      DescendantLoader::ArDescendantsWithLoader,
      Class,
      ...
      Object,
      ...
    ]

but looks like this for ActiveRecord::Base (if we were to rely on the
Class patch only):

    [
      #<Class:ActiveRecord::Base>,
      ...
      ActiveSupport::DescendantsTracker,
      ...
      #<Class:Object>,
      ...
      DescendantLoader::ArDescendantsWithLoader,
      Class,
      ...
      Object,
      ...
    ]

Thus ActiveSupport::DescendantsTracker's definition of descedants wins, unless
we patch ActiveRecord::Base directly.

https://bugzilla.redhat.com/show_bug.cgi?id=1537299
@Fryguy
Copy link
Member Author

Fryguy commented Jan 23, 2018

Note that this just changes the DescendantLoader...there is a follow up PR incoming to change Authenticator to remove some of the unnecessary subclass finding code that was added because of this deficiency in the DescendantLoader.

@miq-bot
Copy link
Member

miq-bot commented Jan 23, 2018

Checked commit Fryguy@104416d with ruby 2.3.3, rubocop 0.52.0, haml-lint 0.20.0, and yamllint 1.10.0
1 file checked, 0 offenses detected
Everything looks fine. 🍰

Copy link
Member

@bdunne bdunne left a comment

Choose a reason for hiding this comment

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

👍 LGTM

@bdunne bdunne merged commit d4ce76f into ManageIQ:master Jan 23, 2018
@bdunne bdunne added this to the Sprint 78 Ending Jan 29, 2018 milestone Jan 23, 2018
@bdunne bdunne assigned bdunne and unassigned jrafanie Jan 23, 2018
@jvlcek
Copy link
Member

jvlcek commented Jan 23, 2018

👍 LGTM Thank you @Fryguy

@jrafanie
Copy link
Member

I dislike autoload and the hackery we need to do 😢 . With that said, this looks like a much better solution than handling non-model classes one at a time.

@Fryguy Fryguy deleted the fix_descendant_loader_for_non_ar_models branch January 23, 2018 18:43
Fryguy added a commit to Fryguy/manageiq that referenced this pull request Jan 23, 2018
After ManageIQ#16867, the
DescendantLoader now works properly with non-AR models such as the
Authenticator.  Much of the code in the Authenticator, such as
require_nested and force_load_authenticator_for is just workarounds
over the issues from DescendantLoader, so these can be removed.
Additionally, the only caller of the authenticator_class was the
validator, so this commit moves the validation code into the
Authenticator class directly, allow us to make all of those
authenticator_class methods private.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1537299
Fryguy added a commit to Fryguy/manageiq that referenced this pull request Jan 23, 2018
After ManageIQ#16867, the
DescendantLoader now works properly with non-AR models such as the
Authenticator.  Much of the code in the Authenticator, such as
require_nested and force_load_authenticator_for is just workarounds
over the issues from DescendantLoader, so these can be removed.
Additionally, the only caller of the authenticator_class was the
validator, so this commit moves the validation code into the
Authenticator class directly, allow us to make all of those
authenticator_class methods private.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1537299
Fryguy added a commit to Fryguy/manageiq that referenced this pull request Jan 23, 2018
After ManageIQ#16867, the
DescendantLoader now works properly with non-AR models such as the
Authenticator.  Much of the code in the Authenticator, such as
require_nested and force_load_authenticator_for is just workarounds
over the issues from DescendantLoader, so these can be removed.
Additionally, the only caller of the authenticator_class was the
validator, so this commit moves the validation code into the
Authenticator class directly, allow us to make all of those
authenticator_class methods private.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1537299
simaishi pushed a commit that referenced this pull request Jan 23, 2018
…r_models

Change DescendantLoader to handle non-AR classes in the models directory
(cherry picked from commit d4ce76f)

https://bugzilla.redhat.com/show_bug.cgi?id=1537788
@simaishi
Copy link
Contributor

Gaprindashvili backport details:

$ git log -1
commit 5ba1310826e1bb842403102665ff3f71ea5c9898
Author: Brandon Dunne <brandondunne@hotmail.com>
Date:   Tue Jan 23 10:49:13 2018 -0500

    Merge pull request #16867 from Fryguy/fix_descendant_loader_for_non_ar_models
    
    Change DescendantLoader to handle non-AR classes in the models directory
    (cherry picked from commit d4ce76fc5ed334e1261089ad7f8a7ac7033b5bde)
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1537788

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants