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

Rails 5.0/5.1 Use o.reload.assoc, assoc(true) is gone #18079

Merged

Conversation

jrafanie
Copy link
Member

@jrafanie jrafanie commented Oct 10, 2018

Note, the before_save was calling remove_invalid_resource on create
which didn't make sense because it was trying to find service_resources
with orphaned resources, which can't happen unless the service_template
itself has been saved. Because of this, it makes sense to change this
to before_update instead of adding r.persisted? checks in the
remove_invalid_resource method.

The force reload parameter was removed from associations in:
rails/rails@09cac8c

It was previously deprecated here:
rails/rails@6eae366

From that commit:

For collections:
@user.posts.reload # Instead of @user.posts(true)

For singular associations:
@user.reload.profile # Instead of @user.profile(true)

Extracted from #18076

Copy link
Member

@NickLaMuro NickLaMuro left a comment

Choose a reason for hiding this comment

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

Putting this as "Request changes" for now, but am going to say I will be easily convinced to change my mind if you can prove I am wrong (very possible).

At least want a discussion around this since the commit I have provided has show some reasonable doubt if this is the right change.

@@ -24,7 +24,7 @@ def self.create_catalog_item(options, _auth_user = nil)

def remove_invalid_resource
# remove the resource from both memory and table
service_resources.to_a.delete_if { |r| r.destroy unless r.resource(true) }
service_resources.to_a.delete_if { |r| r.destroy unless r.resource.reload }
Copy link
Member

Choose a reason for hiding this comment

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

So I think you have this backwards... Or, at least I think you do based on what I think this is a better link for the "change commit" (compared to what you have in the description):

rails/rails@6eae366

Since this is a singular association, I think you want r.reload.resource to clear the objects "association cache", as it were, and then load the object again and confirm nothing is returned from the DB.

The downside I see with this is that it could be more SQL queries then what you have here (one to reload the r, and one to reload the r.resource again), but I think this is then in the spirit of what was trying to be done here. Possibly there is another internal API to just clear the association cache, but unsure. Also unsure if a reload will mess with the r.destroy.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is why I asked you @NickLaMuro. I think you're absolutely right.

While you raise good questions about the number of sql queries, etc., I don't think this is ever called often enough to cause performance concern.

Copy link
Member

@NickLaMuro NickLaMuro Oct 10, 2018

Choose a reason for hiding this comment

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

@jrafanie that is where I would ask the original author of service_template_ansible_tower.rb about this, since I am just guessing what the code is doing based on context (jedi mind trick). Couldn't tell you which is supposed to be "more right".

@jrafanie jrafanie force-pushed the rails_5_1_association_reload_was_removed branch from bc4b079 to 6ac1637 Compare October 11, 2018 16:05
@jrafanie jrafanie changed the title Rails 5.0/5.1 Use assoc.reload, assoc(true) is gone Rails 5.0/5.1 Use o.reload.assoc, assoc(true) is gone Oct 11, 2018
@jrafanie
Copy link
Member Author

jrafanie commented Oct 11, 2018

At least want a discussion around this since the commit I have provided has show some reasonable doubt if this is the right change.

I double checked the original commit and it's just trying to make sure the backing resource for a service resource is gone before deleting it. You were absolutely right.

I updated the commit and description.

Note, the before_save was calling remove_invalid_resource on create
which didn't make sense because it was trying to find service_resources
with orphaned resources, which can't happen unless the service_template
itself has been saved.  Because of this, it makes sense to change this
to before_update instead of adding r.persisted? checks in the
remove_invalid_resource method.

The force reload parameter was removed from associations in:
rails/rails@09cac8c67af

It was previously deprecated here:
rails/rails@6eae366

From that commit:

For collections:
@user.posts.reload   # Instead of @user.posts(true)

For singular associations:
@user.reload.profile # Instead of @user.profile(true)

Extracted from ManageIQ#18076
@jrafanie jrafanie force-pushed the rails_5_1_association_reload_was_removed branch from 6ac1637 to 3f4f8c6 Compare October 11, 2018 18:46
@@ -24,7 +24,7 @@ def self.create_catalog_item(options, _auth_user = nil)

def remove_invalid_resource
# remove the resource from both memory and table
service_resources.to_a.delete_if { |r| r.destroy unless r.resource(true) }
Copy link
Member Author

@jrafanie jrafanie Oct 11, 2018

Choose a reason for hiding this comment

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

@bzwei Can you review this change? I needed to remove the .resource(true) to force reload of the association because .resource doesn't accept any parameters in rails 5.1. The alternative of .reload.resource causes issues because this before_save is called before creates and updates and blows up on creates because it's not yet persisted. I changed this to a before_update, to simplify the code based on the comment you added.

Copy link
Member

Choose a reason for hiding this comment

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

I understand the s/\](true\)/reload

curious:

Do we want to change from delete_if to each? think the to_a negates any real side effects.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, I think this needs to be cleanedup and possibly moved up as you suggested elsewhere. I'm not sure why we need to delete_if on an array we don't retain but that seems besides the point of the PR. I agree, it's needs further refinement.

Copy link
Member

@NickLaMuro NickLaMuro left a comment

Choose a reason for hiding this comment

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

Mostly removing my ❌ here. Will let Bill and crew be the final judge, but looks good from my perspective.

@bzwei
Copy link
Contributor

bzwei commented Oct 11, 2018

@jrafanie LGTM. Thanks for the very detailed explanation.

@miq-bot
Copy link
Member

miq-bot commented Oct 12, 2018

Checked commit jrafanie@3f4f8c6 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
1 file checked, 1 offense detected

app/models/service_template_ansible_tower.rb

  • ❗ - Line 27, Col 54 - Rails/Blank - Use if r.reload.resource.blank? instead of unless r.reload.resource.present?.

@jrafanie
Copy link
Member Author

  • ❗️ - Line 27, Col 54 - Rails/Blank - Use if r.reload.resource.blank? instead of unless r.reload.resource.present?.

Sorry bot, I disagree here. It reads more like English the way it is.

Copy link
Member

@kbrock kbrock left a comment

Choose a reason for hiding this comment

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

Looking good.

Almost feels like the remove_invalid_resource stuff belongs higher up in the chain for ServiceTemplate. Kinda feels like it belongs as a :dependent => :destroy, though that would possibly be anywhere.

@@ -24,7 +24,7 @@ def self.create_catalog_item(options, _auth_user = nil)

def remove_invalid_resource
# remove the resource from both memory and table
service_resources.to_a.delete_if { |r| r.destroy unless r.resource(true) }
Copy link
Member

Choose a reason for hiding this comment

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

I understand the s/\](true\)/reload

curious:

Do we want to change from delete_if to each? think the to_a negates any real side effects.

@@ -1,7 +1,7 @@
class ServiceTemplateAnsibleTower < ServiceTemplate
include ServiceConfigurationMixin

before_save :remove_invalid_resource
Copy link
Member

Choose a reason for hiding this comment

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

+1

@kbrock kbrock merged commit a93cc4d into ManageIQ:master Oct 12, 2018
@kbrock kbrock self-assigned this Oct 12, 2018
@kbrock kbrock added this to the Sprint 97 Ending Oct 22, 2018 milestone Oct 12, 2018
@jrafanie jrafanie deleted the rails_5_1_association_reload_was_removed branch December 14, 2018 17:35
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.

5 participants