-
-
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
#4368 Admin panel - users - edit exist user - update address field always return 200 #4431
base: main
Are you sure you want to change the base?
#4368 Admin panel - users - edit exist user - update address field always return 200 #4431
Conversation
if(Address.new(bill_address_params).valid? && | ||
Address.new(ship_address_params).valid?) |
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 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.
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.
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.
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.
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.
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 also believe we should add a Admin::Users::AddressesController
to directly work on the address records in stead of proxying through the user.
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.
Admin::Users::AddressesController
Yes, I think better update address by callling new AddressesController.
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. |
@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. |
Hi @tvdeyen @jarednorman @waiting-for-dev. Review please my last changes. |
end | ||
end | ||
|
||
def model_class |
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.
Sorry, why do we need it? I don't see it used anywhere else, right?
@user.bill_address = new_bill_address | ||
@user.ship_address = new_shipping_address |
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.
Did you check that it's actually updating the user and not only assigning it in memory?
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, new values will be saved for user. I tested. I reloaded the page and addresses have already been displayed with new values.
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.
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?
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.
@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 |
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'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?
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, people may still have this path in their customized views. We should deprecate this instead (and not remove the route),
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.
@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" } %> |
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.
<%= 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" } %> |
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.
<%= 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) %> |
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.
We also need to restore the indentation here.
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.
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.
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 @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 |
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 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.
backend/config/routes.rb
Outdated
put :addresses | ||
end | ||
|
||
get 'addresses', action: :show, controller: 'addresses', as: :addresses | ||
put 'addresses/update', action: :update, controller: 'addresses', as: :addresses_update |
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.
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' |
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.
Can you please remove this require
?
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 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 👏🏻
backend/config/routes.rb
Outdated
get 'addresses', action: :show, controller: 'addresses', as: :addresses | ||
put 'addresses/update', action: :update, controller: 'addresses', as: :addresses_update |
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.
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
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 |
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
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 |
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.
Can we rename this to load_user
please?
@user.bill_address = new_bill_address | ||
@user.ship_address = new_shipping_address |
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.
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 |
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.
def initial_user | |
def load_user |
@jarednorman old admin closed won't fix |
Issue: #4368