0

In Laravel PHP I have an object which needs some parameters updating. The object is updated and I can return or dd() the correct values. But when I ->save() it's as if the values haven't been changed. The ->save method works fine, but the way I'm updating the object values is obviously wrong somehow...

So using the following code I loop through an array of parameters to update and create an updated object (simplified example) :

      $account = Account::find('account_id');
      // ^returns something like (object)['user'=>['name'=>'jeff','age'=>'20']];

      $to_update = ['user.name':'john', 'user.age':'50'];

      // the following function converts exploded arrays of key names to php objects
      // ie user.name:"John" becomes user->name = john
      function get($path, $object, $value) {
        $temp = &$object;
        foreach($path as $var) {
            $temp =& $temp->$var;
        }
        $temp = $value;
      }

      foreach($to_update as $keys => $value){

        $key = explode(".", $keys);
        get($key, $account, $value);
      }

      // $account->save();

      return $account;

This returns a nice, updated object like :

+"user": +"name":"john" +"age":"50"

HOWEVER if I save that object, it doesn't save the updated values, only the old values. So changing the last two lines :

      $account->save();

      return $account;

results in

+"user": +"name":"jeff" +"age":"20" // these are the old values

So my question is - why does return $account give the correct, updated object, but $account->save(); return $account revert to the original values?

FYI: the following code works (but is too simple for my purposes) :

  $account = Account::find('account_id');
  // ^returns something like (object)['user'=>['name'=>'jeff','age'=>'20']];

  $account->user->name = "jim";
  $account->user->age = "100";

  $account->save();

  return $account;

+"user": +"name":"jim" +"age":"100"

The full dd output of $account BEFORE the save looks like this (this includes my updated values) :

        Account {#642
            +"id": "1234567890"
            +"object": "account"
            +"business_name": "my-business"
            +"business_primary_color": "#c2185b"
            +"business_url": "http://url.com"
            +"charges_enabled": true
            +"country": "GB"
            +"created": 1534491122
            +"debit_negative_balances": false
            +"decline_charge_on": StripeObject {#644
                +"avs_failure": false
                +"cvc_failure": false
            }
            +"default_currency": "gbp"
            +"details_submitted": false
            +"display_name": "display_name"
            +"email": "[email protected]"
            +"external_accounts": Collection {#643
                +"object": "list"
                +"data": []
                +"has_more": false
                +"total_count": 0
                +"url": "external_accounts_url"
            }
            +"legal_entity": StripeObject {#649
                +"additional_owners": []
                +"address": StripeObject {#655
                +"city": null
                +"country": "GB"
                +"line1": null
                +"line2": null
                +"postal_code": null
                +"state": null
                }
                +"business_name": null
                +"business_tax_id_provided": false
                +"dob": StripeObject {#656
                +"day": "01"
                +"month": "01"
                +"year": null
                }
                +"first_name": "john"
                +"last_name": "doe"
                +"personal_address": StripeObject {#659
                +"city": null
                +"country": "GB"
                +"line1": null
                +"line2": null
                +"postal_code": null
                +"state": null
                }
                +"type": "company"
                +"verification": StripeObject {#662
                +"details": null
                +"details_code": null
                +"document": null
                +"document_back": null
                +"status": "unverified"
                }
            }
            +"metadata": StripeObject {#652}
            +"payout_schedule": StripeObject {#665
                +"delay_days": 7
                +"interval": "daily"
            }
            +"payout_statement_descriptor": null
            +"payouts_enabled": false
            +"product_description": null
            +"statement_descriptor": "MY BUSINESS"
            +"support_email": null
            +"support_phone": null
            +"timezone": "Etc/UTC"
            +"tos_acceptance": StripeObject {#670
                +"date": 1535741539
                +"ip": "255.255.255.255"
                +"user_agent": null
            }
            +"type": "custom"
            +"verification": StripeObject {#673
                +"disabled_reason": null
                +"due_by": null
                +"fields_needed": array:6 [
                0 => "external_account"
                1 => "legal_entity.additional_owners"
                2 => "legal_entity.dob.day"
                3 => "legal_entity.dob.month"
                4 => "legal_entity.dob.year"
                5 => "legal_entity.last_name"
                ]
            }
            }
8
  • 2
    Can you post your full dd of $account right before the save? Probably you manipulate the wrong attriutes. Nevertheless I'm not fully sure why you chose such a fairly complex way to update the user of an account. As the account only seems to have 1 user you could simple query for the user at the very first instance and then update it directly from the request paramters like $user->update($request->only(['name', 'age']) Commented Sep 6, 2018 at 12:14
  • 1
    check if this fields are fillable for model Commented Sep 6, 2018 at 12:18
  • 1
    Account::create([$account]); may work if you unguarded all fields in the model? Commented Sep 6, 2018 at 12:35
  • 1
    This is not the full dd of a eloquent model instance. A dd will output all the fields + methods of the model (e.g. laraveldaily.com/echoing-dd-vs-var_dump-vs-print_r) Commented Sep 6, 2018 at 12:44
  • 1
    oh well - I just realize: You are saving the account even though you are making changes to the user. You will probably need to use push instead of save - see this stackoverflow.com/questions/17035682/… Commented Sep 6, 2018 at 12:56

2 Answers 2

1

As you are updating inner entities but calling save on the outer entity it will only update the outer entity and then reload the current relations which have not been updated.

Therefore use $account->push() instead or just $account->user->save() in order to save the correct one.

Eloquent push() and save() difference

Sign up to request clarification or add additional context in comments.

6 Comments

That sounds about right! BUT I cannot use push() directly [call to undefined method push()]. Is there a way to "apply" my changes and THEN save, i wonder...?
$account->user->save(); also results in [call to undefined method save()]
if $accoun->user->save() results in undefined method then user does not return an eloquent model - what is the result of dd($account->user)
It is a StripeObject (JSON) : StripeObject {#649 +"address": StripeObject {#655 +"city": null +"country": "GB" etc...
are you using laravel cashier ? I wasn't aware we are talking about a stripe integration where you actually want to update info on stripe side
|
1

You called save method to account object instead of user object in account to do it use $account->user->save(); or use it if your purpose is to update the same user details do as $account->user->update(['name'=>'jim','age'=>'100']);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.