-
-
Notifications
You must be signed in to change notification settings - Fork 729
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
Split name column in customers table #8763
Changes from all commits
d0f347e
5ca4d54
ba6523b
9b93102
ca46359
7c25127
eefd989
75345a9
23776c7
836a60a
b8afb7e
d016c47
9682b92
5030216
4cb31d0
6d986de
5c9dd81
554a862
07314af
d09ba16
de4d074
9a12957
68193ef
feaa924
fd815a6
4c50ca6
a6dee77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,8 @@ module Api | |
module Admin | ||
class SubscriptionSerializer < ActiveModel::Serializer | ||
attributes :id, :shop_id, :customer_id, :schedule_id, :payment_method_id, :shipping_method_id, | ||
:begins_at, :ends_at, | ||
:customer_email, :customer_name, :schedule_name, :edit_path, :canceled_at, :paused_at, :state, | ||
:begins_at, :ends_at, :customer_email, :customer_first_name, :customer_last_name, | ||
:customer_full_name, :schedule_name, :edit_path, :canceled_at, :paused_at, :state, | ||
:shipping_fee_estimate, :payment_fee_estimate | ||
|
||
has_many :subscription_line_items, serializer: Api::Admin::SubscriptionLineItemSerializer | ||
|
@@ -34,8 +34,16 @@ def customer_email | |
object.customer&.email | ||
end | ||
|
||
def customer_name | ||
object.customer&.name | ||
def customer_first_name | ||
object.customer&.first_name | ||
end | ||
|
||
def customer_last_name | ||
object.customer&.last_name | ||
end | ||
Comment on lines
+37
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does the |
||
|
||
def customer_full_name | ||
object.customer&.full_name | ||
end | ||
|
||
def schedule_name | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# frozen_string_literal: true | ||
|
||
class SplitCustomersName < ActiveRecord::Migration[6.1] | ||
def up | ||
add_column :customers, :first_name, :string, null: false, default: "" | ||
add_column :customers, :last_name, :string, null: false, default: "" | ||
end | ||
|
||
def down | ||
remove_column :customers, :first_name | ||
remove_column :customers, :last_name | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# frozen_string_literal: true | ||
|
||
class MigrateCustomersData < ActiveRecord::Migration[6.1] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call to split! It could have been MigrateCustomersName... |
||
class SpreeAddress < ApplicationRecord; end | ||
|
||
class Customer < ApplicationRecord | ||
belongs_to :bill_address, class_name: "SpreeAddress" | ||
end | ||
|
||
def up | ||
migrate_customer_name_data! | ||
end | ||
|
||
def migrate_customer_name_data! | ||
customers_with_bill_addresses.find_each do |customer| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's what I thought we could do and then Lynne suggested that we don't need this. But okay, it's done now. Nice work. |
||
if bill_address_name_matches?(customer) | ||
apply_name_from_bill_address!(customer) | ||
next | ||
end | ||
|
||
split_customer_name!(customer) | ||
end | ||
|
||
customers_without_bill_addresses.find_each do |customer| | ||
split_customer_name!(customer) | ||
end | ||
end | ||
|
||
def customers_with_bill_addresses | ||
Customer.joins(:bill_address).where(first_name: "", last_name: "").where.not(name: [nil, ""]) | ||
end | ||
|
||
def customers_without_bill_addresses | ||
Customer.where(bill_address_id: nil, first_name: "", last_name: "").where.not(name: [nil, ""]) | ||
end | ||
|
||
def bill_address_name_matches?(customer) | ||
address_name = customer.bill_address.firstname + customer.bill_address.lastname | ||
customer.name.delete(" ") == address_name.delete(" ") | ||
end | ||
|
||
def split_customer_name!(customer) | ||
return if (name_parts = customer.name.split(' ')).empty? | ||
|
||
customer.update_columns( | ||
first_name: name_parts.first, | ||
last_name: name_parts[1..].join(' '), | ||
updated_at: Time.zone.now | ||
) | ||
end | ||
|
||
def apply_name_from_bill_address!(customer) | ||
customer.update_columns( | ||
first_name: customer.bill_address.firstname, | ||
last_name: customer.bill_address.lastname, | ||
updated_at: Time.zone.now | ||
) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# frozen_string_literal: true | ||
|
||
FactoryBot.define do | ||
factory :customer, class: Customer do | ||
email { generate(:random_email) } | ||
enterprise | ||
code { SecureRandom.base64(150) } | ||
user | ||
bill_address { create(:address) } | ||
end | ||
end |
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.
associate_customer
is a before_validation action. After your change, it doesn't have any effect any more. But ifensure_customer
is called then we don't need to callassociate_customer
beforehand anyway. So maybe we can remove that action.openfoodnetwork/app/models/spree/order.rb
Lines 87 to 88 in aea932b
I'm just wondering about edge cases now. So if ensure_customer is executed, it includes associate_customer and everything is good. The logic would only change if ensure_customer is not executed but associate_customer would. The conditions for that is:
So the only case in which we would have tried to associate a customer without creating a new record is when the order is new or in cart state. I could imagine that this is needed to associate tags during shopping to that customer specific products, discounts or fees can be applied.
I'm not sure if this is handled somewhere else but you might be introducing a bug here. I do think that this part of the code needs refactoring but maybe the full refactor is out of scope. I would leave the
self.customer =
in the code to keep the old behaviour here and then we clean it up another time.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.
Actually, I think that I have an idea how to resolve this. I'll add a commit to your branch and we need to extend the testing notes with the case above.
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.
You are right, the
associate_user
method is used inorder_cart_reset.rb
so I guess I am introducing a bug here. I was too optimistic with theprivate
section. I should have checked more carefully.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.
I saw about the mix between
associate_customer
and theensure_customer
methods but I was not sure how to refactor it quickly maintaining the existing specs. I should have refactor the specs first as you did, looks great.