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

[10.x] Fix default pivot model values #46522

Closed
wants to merge 1 commit into from
Closed

[10.x] Fix default pivot model values #46522

wants to merge 1 commit into from

Conversation

iamgergo
Copy link
Contributor

Recently I faced with a situation, when using the withPivotValue method on a BelongsToMany relationship definition does not take effect when saving the pivot record.


I have the following setup:

class User extends Model
{
    public function categories(): BelongsToMany
    {
        return $this->belongsToMany(Category::class, 'subscriptions')
                    ->withPivotValue('type', 'manager')
                    ->using(Subscription::class);
    }

    public function subscriptions(): BelongsToMany
    {
        return $this->belongsToMany(Category::class, 'subscriptions')
                    ->withPivotValue('type', 'player')
                    ->using(Subscription::class);
    }
}
class Subscription extends Pivot
{
    public $table = 'subscriptions';

    protected $attributes = [
        'type' => 'player',
    ];
}

Before the fix, when attaching a category to a user, the pivot attributes that are defined in the withPivotValue method are overridden by the pivot model's $attributes property.

$category = Category::first();
$user = User::first();

$user->categories()->attach($category); // try to attach as a category NOT as a subscription

$user->categories->isEmpty() // true

$user->subscriptions->isEmpty() // false

$user->subscriptions->first()->pivot->role // palyer

So, when I try to attach a category to a user using the categories relation, since it cannot override the default value using the withPivotValue, the attached category model takes place in the wrong relationship. Also, I think this is a bug.


The same Pivot Model can be used in different relationships, so overriding its default attributes from a relationship definition would be great.

@taylorotwell
Copy link
Member

withPivotValue has nothing to do with updates. Only retrievals. You need to specify the pivot values you want when saving.

@iamgergo
Copy link
Contributor Author

@taylorotwell @driesvints The withPivotValue and the withPivot methods are doing two different things.

withPivotValue has nothing to do with updates

The withPivotValue defines a wherePivot statement and sets a pivot value when saving the relation. So it is used when saving relations.

The withPivot method just retrieves a pivot column.

If I want to retrieve pivot data, I have to use the withPivot even if I use withPivotValue as well. For example:

    public function categories(): BelongsToMany
    {
        return $this->belongsToMany(Category::class, 'subscriptions')
                    ->withPivotValue('type', 'manager') // sets the type pivot attribute automatically
                    ->withPivot('type') // retrieves the type attribute
                    ->using(Subscription::class);
    }

Without this fix, the withPivotValue does not work in some scenarios. From my point of view, this is a bug. Please, consider to reopen this PR.

Thank you!

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.

2 participants