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

Remove Spree::UserAddress#archived flag #3852

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mamhoff
Copy link
Contributor

@mamhoff mamhoff commented Dec 1, 2020

Description

This flag is not very useful and gives rise to bugs.

It is not very useful, as we only need it to "resurrect" addresses that
the user inputs newly, but that match an address that has been removed
from the address book in the past for some reason. Why not remove the
join table entry directly? Much simpler, and less code to worry about.

The bug we found that exists only because of the existence of this
column is the following: If an address is added to the address book that
matches an existing user address that is archived, there is a chance of
it throwing a uniqueness validation error, because the uniqueness check
on user/address on the Spree::UserAddress model does not take into
account the "archived" flag.

The third reason why I think this should go is for data protection
reasons: If I call "delete" on a record, I want it to be gone, not
half-gone. And in the case of a join table representing which addresses
a user wants to be presented with again, I very much want it gone.

Not archived.

Note also: Removing this complexity removes explanatory comments in
otherwise straight-forward API endpoints.

Checklist:

  • I have followed Pull Request guidelines
  • I have added a detailed description into each commit message
  • I have updated Guides and README accordingly to this change (if needed)
  • I have added removed tests to cover this change

@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch 3 times, most recently from 7ccde24 to 1905a7e Compare December 1, 2020 17:46
Copy link
Member

@kennyadsl kennyadsl left a comment

Choose a reason for hiding this comment

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

@mamhoff thanks!

I think that your reasoning makes total sense, it took me a while to get it only reading the PR description because of a mistake:

Why not remove the join table entry directly?

Should be

Why not remove the record from the join table entry directly?

I think that fixing it could help readers from the future to avoid confusion.

In terms of PR's content, I also can't find a reason not to remove the record, instead of resurrecting an old one but I think we should deprecate the usage of archived instead of removing the column, which in my opinion is too invasive and gives for granted that people are not using that field with some custom code.

I also considered using Discard (which at least would be consistent with the rest of the code) + remove the "resurrecting" logic but honestly, I'd avoid it here since it's just a record on a join table and I can't see any point where we may have some value in soft-deleting.

core/app/models/spree/user_address.rb Show resolved Hide resolved
@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch from 1905a7e to 2323468 Compare January 20, 2022 10:29
@mamhoff
Copy link
Contributor Author

mamhoff commented Jan 20, 2022

Rebased this PR on the current master branch. I've also added deprecation warnings for the scopes Spree::UserAddress.archived and Spree::UserAddress.all_historical.

@mamhoff
Copy link
Contributor Author

mamhoff commented Jan 20, 2022

@kennyadsl I changed the wording of the commit message.

I've also kept the scopes to return all records instead of their custom behavior. If stores make use of that archived Boolean (I really doubt it), they are free to empty the migration on upgrading and overriding the new to the old behavior in their stores. I have a really, really hard time imagining this was used for anything anywhere.

@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch 2 times, most recently from af03ace to 86ec7d0 Compare March 22, 2022 22:39
@mamhoff
Copy link
Contributor Author

mamhoff commented Mar 30, 2022

From @kennyadsl : Check if default billing / default shipping addresses are preserved with this change

kennyadsl
kennyadsl previously approved these changes Mar 30, 2022
@kennyadsl kennyadsl dismissed their stale review March 30, 2022 10:36

wrong PR! :P

@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch 2 times, most recently from 225e964 to 9ae594a Compare March 30, 2022 15:55
@kennyadsl
Copy link
Member

@mamhoff looks good but I don't understand why the commit states "Behavior change". I'm not sure to follow which behavior changed. Are you saying that at the moment, when we are "changing" an address that was set as the default, the resulting new immutable address won't have the default (ship or bill) boolean set? If yes, this is probably worth a separate PR?

@mamhoff
Copy link
Contributor Author

mamhoff commented Apr 11, 2022

Yes, i think that is what happens :) I'll provide a separate PR

@mamhoff mamhoff mentioned this pull request Apr 12, 2022
3 tasks
@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch 2 times, most recently from 0d1d4d7 to cf90855 Compare April 19, 2022 12:54
@mamhoff
Copy link
Contributor Author

mamhoff commented Apr 19, 2022

@kennyadsl Extracted the behavior change to #4332, care to re-review? :)


class RemoveArchivedUserAddresses < ActiveRecord::Migration[5.2]
def up
Spree::UserAddress.where(archived: true).delete_all
Copy link
Member

Choose a reason for hiding this comment

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

I'm still a little bit scared about this. We are assuming people are only using this field in the way we think but it's not guaranteed.

Maybe we can keep the archived column (ignoring it on the Rails side) and use the bin/rails g solidus:update task to be sure people are understanding that those records will be deleted from their database. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

@waiting-for-dev correct me if I'm wrong here, but if I recall correctly it's a matter of adding a new method in the update generator, isn't it?

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 really can't imagine that - and if we leave the field, we'll have to deal with it in every upgrade from now on (similar to the Spree::Shipment#deprecated_address_id field. I'd rather add a large changelog entry, and be done with it. People who use the archived flag for something will still be able to edit the migration on their project to not delete the records / column.

Copy link
Member

Choose a reason for hiding this comment

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

Using ignored_columns I think it will be pretty transparent for us.

In my opinion, it's not a matter of imagining how the feature could be used, but more of a formal process of making this software as compliant with SemVer as possible. And removing a table column in a minor release is definitely a breaking change from all possible points of view.

For Spree::Shipment#deprecated_address_id (#4333), it is a bit different because we are not using that field in the code from 2016 as you mentioned in the PR, so it's very unlikely that it is being used. BTW, I think that PR should go in a major release as well. I didn't comment because I just missed it. 🙂

Copy link
Contributor

Choose a reason for hiding this comment

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

@waiting-for-dev correct me if I'm wrong here, but if I recall correctly it's a matter of adding a new method in the update generator, isn't it?

Do you mean adding a message? Yes, we could do that by adding a new method. However, the actual code is already redirecting people to the Changelog. I think it'd be better to add any information there and keep using it as the unique source of truth for upgrades info.

Copy link
Contributor

Choose a reason for hiding this comment

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

Basically, this way we won't have to remember removing the new message before the next Solidus version 😉

@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch from cf90855 to f6c3e38 Compare April 19, 2022 13:26
Copy link
Member

@tvdeyen tvdeyen left a comment

Choose a reason for hiding this comment

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

I think we should be less strict on semver with this change, because this change has never been visible to users and or admins. It is completely hidden from any UI. We even do not have an address book UI. The only potential users of this "feature" would have been developers and or data analysts. But I bet this is not used by anyone. This causes a lot of confusion and complex code.

What this does is, that it mimics discard where it is not necessary, because addresses are not actually removed, but just removed from the users addresses. This causes lots of confusion.

We recently migrated a store from spree to solidus and were very confused still seeing deleted addresses in the users address books.

I am for removing this even in a minor version. 👍🏻

api/spec/requests/spree/api/address_books_spec.rb Outdated Show resolved Hide resolved
api/spec/requests/spree/api/address_books_spec.rb Outdated Show resolved Hide resolved
@kennyadsl
Copy link
Member

I'm ok removing the feature entirely in a minor version. Just saying that maybe we can postpone the database column removal to the next major by just using ignored_columns on the model. Any eventual confusion will be gone because that field is explicitly ignored, and we can keep any unexpected usage of that column safe.

On the other hand, when archived = true the record will be removed from the database, so if someone is using that column for some reason, they will lose a lot of those records anyway, unless they change the migration manually, but at that point, they can also change the removal of the field if needed.

I will bring this to the core team meeting later today and will get back with a shared decision. Thanks again!

@mamhoff
Copy link
Contributor Author

mamhoff commented Apr 20, 2022

I'm ok removing the feature entirely in a minor version. Just saying that maybe we can postpone the database column removal to the next major by just using ignored_columns on the model. Any eventual confusion will be gone because that field is explicitly ignored, and we can keep any unexpected usage of that column safe.

If we use ignored_columns, then anyone actually using the column would have to metaprogram themselves out of us having invoked it. Not sure that would improve the (imo extremely unlikely) situation.

@kennyadsl
Copy link
Member

With metaprogram themselves out of us having invoked it do you mean decorating the model and removing the field from the ignored_columns list, or there's anything more complex to do that I am missing? I thought it was just a matter of doing that but maybe I'm not considering some other things.

By the way, even if it's just that, it's not less complex than manually changing the migration so that nothing happens.

@kennyadsl
Copy link
Member

As is, I'd push this as well in the next major. Since it's not that far I think it's a good idea to avoid removing columns from the database in a minor.

@kennyadsl kennyadsl added this to the 4.0 milestone May 9, 2022
@mamhoff
Copy link
Contributor Author

mamhoff commented May 9, 2022

Should I remove the deprecated scopes here entirely then, or deprecate for Solidus 5?

@kennyadsl
Copy link
Member

If there's a way of deprecating this without removing the database column (eg. as with ignored_columns), I think we can merge this immediately, and only remove the column with Solidus 4. Makes sense?

@waiting-for-dev waiting-for-dev added the release:major Breaking change on hold until next major release label Jun 15, 2022
@waiting-for-dev waiting-for-dev added type:enhancement Proposed or newly added feature changelog:solidus_api Changes to the solidus_api gem changelog:solidus_core Changes to the solidus_core gem labels Aug 24, 2022
core/app/models/spree/user_address.rb Outdated Show resolved Hide resolved
core/app/models/spree/user_address.rb Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
@mamhoff mamhoff requested a review from a team as a code owner April 25, 2023 13:03
@github-actions github-actions bot added changelog:repository Changes to the repository not within any gem and removed changelog:repository Changes to the repository not within any gem labels Apr 25, 2023
@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch from 00bfb41 to 3a5064a Compare April 25, 2023 13:08
@github-actions github-actions bot added the changelog:repository Changes to the repository not within any gem label Apr 25, 2023
@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch from ea45854 to 2210e19 Compare April 25, 2023 13:09
@mamhoff
Copy link
Contributor Author

mamhoff commented Apr 25, 2023

Rebased fromn master, removed the changelog entries (as I assume they're added back in when y'all release).

CHANGELOG.md Outdated
See https://github.com/solidusio/solidus/releases/tag/v1.0.0
Copy link
Contributor

Choose a reason for hiding this comment

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

Non-blocking, but ideally, we shouldn't have any diff with the Changelog.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

This flag is not very useful and gives rise to bugs.

It is not very useful, as we only need it to "resurrect" addresses that
the user inputs newly, but that match an address that has been removed
from the address book in the past for some reason. Why not remove the
record from the join table directly? Much simpler, and less code to worry about.

The bug we found that exists only because of the existence of this
column is the following: If an address is added to the address book that
matches an existing user address that is archived, there is a chance of
it throwing a uniqueness validation error, because the uniqueness check
on user/address on the Spree::UserAddress model does not take into
account the "archived" flag.

The third reason why I think this should go is for data protection
reasons: If I call "delete" on a record, I want it to be gone, not
half-gone. And in the case of a join table representing which addresses
a user wants to be presented with again, I very much want it gone.

Not archived.

Note also: Removing this complexity removes explanatory comments in
otherwise straight-forward API endpoints.
@mamhoff mamhoff force-pushed the remove-archived-user-addresses branch from 2210e19 to 5185400 Compare April 25, 2023 14:39
@github-actions github-actions bot removed the changelog:repository Changes to the repository not within any gem label Apr 25, 2023
@kennyadsl
Copy link
Member

Again, sorry for raising this only now, but we were thinking about alternative paths to deprecate removing this column. We were thinking about this approach but we are not 100 sure it's the best approach yet. Leaving here for documentation.

In the first minor:

  1. create a preference called something like delete_user_addresses_instead_of_archiving
  2. deprecate having the above preference at the false value
  3. in remove_from_address_book method, conditionally destroy records instead of archiving

In a subsequent minor (to be sure that code has been deployed):

  1. add another preference called ignore_active_scope_for_user_addresses. This requires users to have deleted the archived: true records after setting the above preference (delete_user_addresses_instead_of_archiving) to true.
  2. deprecate using the active state, saying in the warning to turn the second preference on.

On the next major, we can remove deprecated code and the column safely.

@elia elia modified the milestones: 4.0, 5.0 Jun 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog:solidus_api Changes to the solidus_api gem changelog:solidus_core Changes to the solidus_core gem release:major Breaking change on hold until next major release type:enhancement Proposed or newly added feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants