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

#4368 Admin panel - users - edit exist user - update address field always return 200 #4431

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

dborovsky
Copy link

Issue: #4368

Comment on lines 163 to 164
if(Address.new(bill_address_params).valid? &&
Address.new(ship_address_params).valid?)
Copy link
Member

Choose a reason for hiding this comment

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

I don't think that this approach makes sense given that the attributes are immutably merged with the existing address. I'm pretty sure that's how that works, anyway.

Copy link
Member

Choose a reason for hiding this comment

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

With this approach we do not have error messages on the addresses that we could display.

I am puzzling with

@user.update(user_params) && @user.bill_address.valid? && @user.ship_address.valid?

but it does not seem to work either.

Copy link
Member

@tvdeyen tvdeyen Jun 23, 2022

Choose a reason for hiding this comment

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

We use nested_attributes for users ship_address and bill_address, but since Spree::Address is read-only it silently (thanks rails) rejects. The address is always valid, because it never updates. We need a way to use Spree::Address.immutable_merge on an existing user.x_address instances somehow.

Copy link
Member

Choose a reason for hiding this comment

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

I also believe we should add a Admin::Users::AddressesController to directly work on the address records in stead of proxying through the user.

Copy link
Author

Choose a reason for hiding this comment

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

Admin::Users::AddressesController

Yes, I think better update address by callling new AddressesController.

@waiting-for-dev
Copy link
Contributor

Thanks for your collaboration, @dborovsky!

I think it'd be good to start with a failing test to ensure that the work done is fixing it. Have you been able to isolate what caused the response to be a success even when the attributes weren't saved?

Please, let me know if you need anything.

@tvdeyen
Copy link
Member

tvdeyen commented Jun 23, 2022

@dborovsky Thanks for the contribution, but I think the issue is in how addresses work in Solidus (they are immutable). The solution is a bit more involved. Do you still want to try working on it? I left some comments about what I currently think could solve the issue.

@dborovsky dborovsky requested review from tvdeyen and jarednorman July 4, 2022 08:15
@dborovsky
Copy link
Author

Hi @tvdeyen @jarednorman @waiting-for-dev. Review please my last changes.

@kennyadsl kennyadsl added type:bug Error, flaw or fault changelog:solidus_backend Changes to the solidus_backend gem labels Aug 22, 2022
end
end

def model_class
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, why do we need it? I don't see it used anywhere else, right?

Comment on lines +15 to +16
@user.bill_address = new_bill_address
@user.ship_address = new_shipping_address
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you check that it's actually updating the user and not only assigning it in memory?

Copy link
Author

Choose a reason for hiding this comment

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

yes, new values will be saved for user. I tested. I reloaded the page and addresses have already been displayed with new values.

Copy link
Member

Choose a reason for hiding this comment

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

Can we make the same check for user_id here as well and only update both user addresses if it is present? Then update the one record (passed as id), to be inline with the rest of the resource controllers and be RESTful in those cases?

Copy link
Author

Choose a reason for hiding this comment

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

@tvdeyen sorry, I don't fully understand what you mean?

Then update the one record (passed as id), to be inline with the rest of the resource controllers and be RESTful in those cases?

@@ -53,16 +53,6 @@ def update
end
end

def addresses
Copy link
Contributor

@waiting-for-dev waiting-for-dev Aug 30, 2022

Choose a reason for hiding this comment

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

I'm afraid we need to deprecate the endpoint before removing it straight away, as some users might have overridden it. You take a look at how we did something similar here: https://github.com/solidusio/solidus/pull/4388/files.

What do you think, @kennyadsl? Or can we remove it now?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, people may still have this path in their customized views. We should deprecate this instead (and not remove the route),

Copy link
Author

Choose a reason for hiding this comment

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

@waiting-for-dev @kennyadsl I added deprecation warning only to put endpoint addresses.

New get endpoint path addresses is the same as the old one

@@ -4,7 +4,7 @@
<fieldset class="no-border-bottom">
<legend align="center"><%= t('spree.billing_address') %></legend>
<%= f.fields_for :bill_address, @user.bill_address || Spree::Address.build_default do |ba_form| %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: ba_form, type: "billing" } %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: ba_form, type: "billing" } %>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<%= render partial: 'spree/admin/shared/address_form', locals: { f: ba_form, type: "billing" } %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: ba_form, type: "billing" } %>

@@ -13,7 +13,7 @@
<fieldset class="no-border-bottom">
<legend align="center"><%= t('spree.shipping_address') %></legend>
<%= f.fields_for :ship_address, @user.ship_address || Spree::Address.build_default do |sa_form| %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: sa_form, type: "shipping" } %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: sa_form, type: "shipping" } %>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<%= render partial: 'spree/admin/shared/address_form', locals: { f: sa_form, type: "shipping" } %>
<%= render partial: 'spree/admin/shared/address_form', locals: { f: sa_form, type: "shipping" } %>

<%= render partial: 'spree/admin/shared/edit_resource_links', locals: { collection_url: admin_users_url } %>
</div>
<% end %>
<% if can?(:update, @user) %>
Copy link
Contributor

Choose a reason for hiding this comment

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

We also need to restore the indentation here.

Copy link
Contributor

@waiting-for-dev waiting-for-dev left a comment

Choose a reason for hiding this comment

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

Sorry for taking so long before looking into it, @dborovsky 🙏 It's looking good. I left some preliminary comments. Let me know what you think.

@github-actions github-actions bot added the changelog:solidus_core Changes to the solidus_core gem label Sep 4, 2022
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.

Thanks @dborovsky! I left some other comments related to backward compatibility and routes shape, but overall this is a good job. I think we are close to merging, thanks again!

@@ -168,9 +168,12 @@
member do
get :orders
get :items
get :addresses
Copy link
Member

Choose a reason for hiding this comment

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

I still have a concern related to backward compatibility related to these routes changes: am I right that the route helper method addresses_admin_user_path is no more available (it's called admin_user_addresses_path now)? If yes, I think we should keep it somehow.

put :addresses
end

get 'addresses', action: :show, controller: 'addresses', as: :addresses
put 'addresses/update', action: :update, controller: 'addresses', as: :addresses_update
Copy link
Member

Choose a reason for hiding this comment

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

As mentioned here, it's probably fine to skip the _update part in the as: argument. The PUT verb is already telling routes which action to take. Can we try without it please?

# frozen_string_literal: true

require 'spec_helper'
require 'pry'
Copy link
Member

Choose a reason for hiding this comment

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

Can you please remove this require?

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.

This is a great step in the right direction. Thanks for addressing this (pun indented)

I would like this to be more RESTful and check for the existence of a @user for the edit and update actions. In all other cases it should handle single addresses.

BTW. this is a great step into finally having a Admin -> User -> Addressbook feature 👏🏻

Comment on lines 174 to 175
get 'addresses', action: :show, controller: 'addresses', as: :addresses
put 'addresses/update', action: :update, controller: 'addresses', as: :addresses_update
Copy link
Member

Choose a reason for hiding this comment

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

The /update part in the url is also not necessary. Rails will be able to resolve the route from the HTTP verb and presence of an id. Also we can use the to keyword to combine controller and action into

Suggested change
get 'addresses', action: :show, controller: 'addresses', as: :addresses
put 'addresses/update', action: :update, controller: 'addresses', as: :addresses_update
get :addresses, to: 'addresses#show', as: :addresses
put :addresses, to: 'addresses#update, as: :addresses

Copy link
Member

Choose a reason for hiding this comment

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

Actually

Suggested change
get 'addresses', action: :show, controller: 'addresses', as: :addresses
put 'addresses/update', action: :update, controller: 'addresses', as: :addresses_update
get :addresses, to: 'addresses#edit', as: :addresses
put :addresses, to: 'addresses#update, as: :addresses

module Spree
module Admin
class AddressesController < Spree::Admin::BaseController
before_action :initial_user
Copy link
Member

Choose a reason for hiding this comment

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

Can we rename this to load_user please?

Comment on lines +15 to +16
@user.bill_address = new_bill_address
@user.ship_address = new_shipping_address
Copy link
Member

Choose a reason for hiding this comment

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

Can we make the same check for user_id here as well and only update both user addresses if it is present? Then update the one record (passed as id), to be inline with the rest of the resource controllers and be RESTful in those cases?


private

def initial_user
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
def initial_user
def load_user

@fthobe
Copy link
Contributor

fthobe commented Feb 8, 2025

@jarednorman old admin closed won't fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog:solidus_backend Changes to the solidus_backend gem changelog:solidus_core Changes to the solidus_core gem type:bug Error, flaw or fault
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants