-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Migrate default billing addresses to address book #3838
Migrate default billing addresses to address book #3838
Conversation
core/db/migrate/20201111133031_migrate_default_billing_addresses_to_address_book.rb
Outdated
Show resolved
Hide resolved
core/db/migrate/20201111133031_migrate_default_billing_addresses_to_address_book.rb
Outdated
Show resolved
Hide resolved
06eef4f
to
f83707b
Compare
Ref: #3563 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving although this ideally should be a data migration that runs in a potential solidus:upgrade
rake task. We had this rake task once (back in 1.x times) but this was unfortunately removed.
Anyhow. Thanks 👍
|
||
class MigrateDefaultBillingAddressesToAddressBook < ActiveRecord::Migration[5.2] | ||
def up | ||
adapter_type = connection.adapter_name.downcase.to_sym |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this again, I think we should add a safe guard here. Since we already shipped this code maybe someone already migrated their data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is true also for people that already updated to 2.11 and has some address with default_billing to true, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I've added a safeguard so that the migration does not do anything if any default_billing flags are already set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that only avoids the migration (and the fix) to run for people that used 2.11 for some time before this will be released, isn't it? The ideal would be something that fixes their database as well. Do you think it's possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mamhoff any thoughts on this? Not sure I was clear enough, I meant that I think this will prevent the issue to happen only for users upgrading from Solidus 2.10.x
to 2.11.4
(assuming 2.11.4
will contain this fix), but doesn't cover who upgrades from 2.11.3
to 2.11.4
. Does it make sense?
f83707b
to
686b9a1
Compare
Hi, thank you for this fix 🐛 👍 ! Below I have a suggestion, tested locally, in addition to your fix, to account for any codebase that already uses the def up
# Safely migrate to the use of `default_billing` if the boolean was already used for the default address.
if Spree::UserAddress.where(default_billing: true).any?
(Spree::User.select { |user| user.bill_address_id && !user.bill_address })
.each { |user| Spree::UserAddress.find_by(user_id: user.id, address_id: user.bill_address_id).update_attribute(:default_billing, true) }
return true
end
adapter_type = connection.adapter_name.downcase.to_sym
if adapter_type == :mysql2
sql = <<~SQL
UPDATE spree_user_addresses
JOIN spree_users ON spree_user_addresses.user_id = spree_users.id
AND spree_user_addresses.address_id = spree_users.bill_address_id
SET spree_user_addresses.default_billing = true
SQL
else
sql = <<~SQL
UPDATE spree_user_addresses
SET default_billing = true
FROM spree_users
WHERE spree_user_addresses.address_id = spree_users.bill_address_id
AND spree_user_addresses.user_id = spree_users.id;
AND spree_users.bill_address != true
SQL
end
execute sql
end
def down
# Safely rollback the use of `default_billing` if the boolean was used for the default address.
if Spree::UserAddress.where(default_billing: true).any?
(Spree::User.select { |user| user.bill_address })
.each { |user| user.update_attribute(:bill_address_id, user.bill_address.id) }
end
Spree::UserAddress.update_all(default_billing: false) # rubocop:disable Rails/SkipsModelValidations
end |
Hey @ikraamg thank you - However, for a very large Solidus installation, this will be prohibitively slow. I've purposefully set this to run in pure SQL, and I'm sure it's possible to do this without iterating over ActiveRecord collections. Sometime this week :) |
Hi @mamhoff, @DanielePalombo helped out with a solution where we exclude the if Spree::UserAddress.where(default_billing: true).any?
Spree::User.joins(:bill_address).update_all(bill_address_id: nil)
end
.... It probably also should be moved to a dedicated rake task as Thomas mentioned. |
The task is created in a PR to this branch, however, I am unsure where to run the task as we do not have the |
core/spec/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book_spec.rb
Outdated
Show resolved
Hide resolved
core/spec/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book_spec.rb
Outdated
Show resolved
Hide resolved
core/spec/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book_spec.rb
Outdated
Show resolved
Hide resolved
core/spec/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book_spec.rb
Outdated
Show resolved
Hide resolved
core/spec/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book_spec.rb
Outdated
Show resolved
Hide resolved
d31e393
to
c09dc03
Compare
core/db/migrate/20200320144521_add_default_billng_flag_to_user_addresses.rb
Outdated
Show resolved
Hide resolved
c09dc03
to
ca3ea85
Compare
@ikraamg @DanielePalombo Thank you for moving this ahead! I've merged @ikraamg s Pull Request and fixed a few whitespace issues, but I think this should be good to go now :) |
CHANGELOG.md
Outdated
@@ -1,5 +1,13 @@ | |||
## Solidus 3.0.0 (master, unreleased) | |||
|
|||
Migrated default billing addresses to address book |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not go into the 3.0 changelog, we need to backport this task into 2.11.x. I'll take care of the changelog, you can remove this entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will remove this when I add the test case.
core/spec/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book_spec.rb
Show resolved
Hide resolved
@mamhoff I have made the fixes that @kennyadsl requested in a new PR: mamhoff#2. Then after a squash here, I think we are ready to merge this PR 👍 |
`Spree::User` records have a `bill_address_id` that denotes their saved billing address to be reused in the next checkout. That column, however, is not in use since Solidus 2.11.0. Instead, we rely on a `default_billing` Boolean on the `spree_user_addresses` join table. This migration sets the `default_billing` flag on that join table for addresses matching the user's default billing address and the user's ID. MySQL has different SQL syntax than standard SQL, which is why we need two SQL statements. For stores that have run this or a similar migration before, there's a safeguard so they remember to fix their migrations when they upgrade. Co-authored-by: mamhoff <[email protected]> Co-authored-by: DanielePalombo <[email protected]> Co-authored-by: Ikraam Ghoor <[email protected]>
34eb833
to
c91b470
Compare
@ikraamg @DanielePalombo @kennyadsl merged and squashed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @mamhoff @ikraamg @DanielePalombo !
Description
Spree::User
records have abill_address_id
that denotes their savedbilling address to be reused in the next checkout. That column, however,
is not in use since Solidus 2.11.0. Instead, we rely on a
default_billing
Boolean on thespree_user_addresses
join table.This migration sets the
default_billing
flag on that join table foraddresses matching the user's default billing address and the user's ID.
Checklist: