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

[11.x] Apply relation constraints on upsert #52239

Merged
merged 3 commits into from
Jul 26, 2024
Merged

Conversation

iamgergo
Copy link
Contributor

Currently when using upsert via a relationship (HasOne, HasMany, MorphOne, MorhpMany) we need to pass the foreign key (and morph type) explicitly.

For example I have a User model with a has many relation called consents. Before this PR we have to pass the user_id => 4 explicitly for the records (for polymorphic relation the morph type as well).

After the PR these values are filled automatically:

User::find(4)->consents()->upsert(
    [
        ['type' => 'foo', 'value' => 'disabled'],
        ['type' => 'bar', 'value' => 'enabled'],
    ],
    ['user_id', 'type'], 
    ['value']
);

In other relationship methods like create, updateOrCreate or save Eloquent already does the job for us.

@taylorotwell taylorotwell merged commit 7c42890 into laravel:11.x Jul 26, 2024
29 checks passed
@iamgergo iamgergo changed the title [11.x] Apply relation constraitns on upsert [11.x] Apply relation constraints on upsert Jul 26, 2024
@dwightwatson
Copy link
Contributor

dwightwatson commented Jul 26, 2024

Hi - I think this may have issues when using upsert with morphOne? After updating to Laravel 11.18 which includes this change I now have Cannot use a scalar value as an array being thrown in my test suite.

Error: Cannot use a scalar value as an array in /Users/dwight/Sites/roomies/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphOneOrMany.php:110

It looks like before this PR it was possible to only pass a single array into upsert, but now you need to pass an array of arrays?

$this->listing()->upsert(
    [
        'user_id' => $this->user->id,
        'listable_id' => $this->id,
        'listable_type' => $this::class,
        'activated_at' => $this->activated_at,
        'updated_at' => $this->updated_at,
    ],
    uniqueBy: ['listable_id', 'listable_type'],
    update: ['user_id', 'activated_at', 'updated_at'],
);

Edit: if I update my upsert's first argument to be an array of array it works as expected. Re-reading the documentation now it only shows upsert being used with an array of arrays so I'm not sure if this is intended or not.

@driesvints
Copy link
Member

@iamgergo ^

@iamgergo
Copy link
Contributor Author

You're right! I'm not sure either whether passing a "flat" array is intended or not.

I try to fix this very soon! Thanks!

@szepeviktor
Copy link
Contributor

@iamgergo
Copy link
Contributor Author

#52289

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants