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

Fix ActiveStorage has_many_attached when record is not persisted #42383

Merged

Conversation

intrip
Copy link
Contributor

@intrip intrip commented Jun 4, 2021

Summary

This is a follow up of #42256.

Purging a not persisted record no longer raise an error forhas_many_attached.

Moves the purge and purge_later logic of ActiveStorage::Attached to Attached::Changes API.

@intrip
Copy link
Contributor Author

intrip commented Jun 4, 2021

@zzak @pixeltrix Could you please take a look and LMK your take on this 🙇 ?

@zzak
Copy link
Member

zzak commented Jun 4, 2021

@intrip I think of delete/purge as a change, so rather than creating a Base class and adding this change to every interface (even create was surprising) let's figure out how we can introduce this into "changes" api.

The fact that we have to define Attached::Changes::CreateOne.purge and Attached::Changes::CreateOne.purge_later feels like we're doing something wrong 🤔

@intrip
Copy link
Contributor Author

intrip commented Jun 4, 2021

@zzak thanks for the feedback!

I think of delete/purge as a change, so rather than creating a Base class and adding this change to every interface (even create was surprising) let's figure out how we can introduce this into "changes" api.

The fact that we have to define Attached::Changes::CreateOne.purge and Attached::Changes::CreateOne.purge_later feels like we're doing something wrong 🤔

Gotcha, let's reason together around it:

  • purge/purge_later are actually parts of the attached public API (not the changes API)
    • the proposal of moving the purge methods implementations to the "changes" objects is because from the attached API we work with both changes and AR association in the same purge method; the idea is to let each object deal with his own data
  • the upload method is also part of the changes API, isn't it the opposite of the purge method (hence they are related 🤷‍♂️ ) ?

Your proposal is to create two new classes Attached::Changes::PurgeOne/Attached::Changes::PurgeMany in order to deal with purges?

LMK your thoughts and please forgive me if I'm overlooking at something.

@zzak
Copy link
Member

zzak commented Jun 4, 2021

@intrip Thanks for thinking about this, and apologies for a half-baked response it was at the end of my day 😅

I think we're on the same page, we would have to add two new classes for the PurgeOne and PurgeMany changes.

Would you mind giving that some more thought and maybe trying it out?

@intrip intrip force-pushed the has-many-attached-attachment-not-persisted branch 2 times, most recently from a0d6549 to d020c47 Compare June 7, 2021 11:03
Comment on lines 157 to 165
def purge
each(&:purge)
reset
end

def purge_later
each(&:purge_later)
reset
end
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we can remove this:

  • This extension is no longer called from the Attached API
  • I didn't see any documentation explicitly referring to #{name}_attachments.purge/purge_later
  • No tests are using this extension explicitly

For the above reasons shouldn't be a breaking change and allows us to avoid a maintenance burden.

Copy link
Member

Choose a reason for hiding this comment

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

@intrip Are these public API? We could add a deprecation (in a follow-up PR)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Honestly I'm not sure (hence my comment above): Is public API a method which has public visibility but is not documented and doesn't have an explicitly # :nodoc: comment? 🤷‍♂️

@intrip
Copy link
Contributor Author

intrip commented Jun 7, 2021

@zzak I've followed your suggestion in #42383 (comment)

Could you please check again ?

@intrip intrip force-pushed the has-many-attached-attachment-not-persisted branch from d020c47 to f2f57b0 Compare June 9, 2021 06:59
@intrip intrip force-pushed the has-many-attached-attachment-not-persisted branch 3 times, most recently from 217d6f7 to 4a99f2c Compare June 9, 2021 08:34
@intrip
Copy link
Contributor Author

intrip commented Jun 9, 2021

@zzak thanks!
I've answered your questions and also noted something interesting in #42383 (comment). Could you please check again 🙇 ?

@zzak
Copy link
Member

zzak commented Jun 9, 2021

I think we should not remove the purge/purge_later version (in this PR).

Unless the parent class/module is already :nodoc: we can assume all methods inside are public API (unless method visibility is already private).

But perhaps @pixeltrix has some more ideas here, particularly w/r/t this thread: #42383 (comment)

Raising this in the comments since it's easy for code-threads to get lost 😭

@intrip intrip force-pushed the has-many-attached-attachment-not-persisted branch from 4a99f2c to f490b8e Compare June 11, 2021 15:50
@intrip
Copy link
Contributor Author

intrip commented Jun 11, 2021

@zzak I've postponed the removal of purge/purge_later as you suggested in #42383 (comment)
I've also followed your suggestion to fix the docs.

Please LMK if you have anything else to add 🙇

@zzak
Copy link
Member

zzak commented Jun 11, 2021

@intrip Nice work! Thanks for putting this together 🙏

@zzak zzak added the ready PRs ready to merge label Jun 11, 2021
@zzak zzak requested a review from pixeltrix June 11, 2021 23:11
This is a follow up of rails#42256.

Purging a not persisted record no longer raise an error for
`has_many_attached`.

Moves the `purge` and `purge_later` logic of `ActiveStorage::Attached`
to `Attached::Changes` API.
@intrip intrip force-pushed the has-many-attached-attachment-not-persisted branch from f490b8e to a8a6065 Compare June 12, 2021 17:49
@pixeltrix
Copy link
Contributor

@intrip @zzak thanks for sorting this out 👍🏻

Just one thing before I merge - are the association extensions purge and purge_later in model.rb now redundant?

has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy, strict_loading: strict_loading do
def purge
each(&:purge)
reset
end
def purge_later
each(&:purge_later)
reset
end
end

@intrip
Copy link
Contributor Author

intrip commented Jun 13, 2021

@pixeltrix thanks for checking!

Just one thing before I merge - are the association extensions purge and purge_later in model.rb now redundant?

Yes: If you check #42383 (comment) I've proposed to remove that but we weren't sure if we should do it in this PR or we should do it in two separate PRs with a deprecation warning + removal after a new release.

What's your take on this?

@pixeltrix
Copy link
Contributor

What's your take on this?

Hmm, so those methods would only be called now if you call the association directly - not sure how much that code path would've been used but @zzak is right, we should deprecate them first.

@intrip
Copy link
Contributor Author

intrip commented Jun 14, 2021

@pixeltrix thanks for feedback.

I'll make a follow-up PR which introduces the deprecation warning.

@pixeltrix pixeltrix merged commit 051b0fc into rails:main Jun 14, 2021
@pixeltrix
Copy link
Contributor

@intrip thanks! 👍🏻

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

Successfully merging this pull request may close these issues.

None yet

3 participants