#`->attach()` is bulk inserting for one model but not another. Both using `belongsToMany`.

2 messages · Page 1 of 1 (latest)

junior cedar
#

I'm running into an issue where the ->attach() method will bulk insert for one model but not another and thereby creating an n+1 insert of hundreds or potentially thousands of queries.

For example, in one scenario I have both a Collection model (not to be confused with a collection in Laravel) and a Account model with a belongsToMany relationship. I'm attaching a bunch of accounts to a collection with the following code:

$collection = Collection::findOrFail($data['collection']);
$chunks = $selectedAccounts->diff($collection->accounts)->pluck('id')->chunk(500);
$chunks->each(fn ($chunk) => $collection->accounts()->attach($chunk));

This works great and does one bulk insert.

Now, in another scenario, I have both a Campaign model and a Account model, again with a belongsToMany relationship. I'm attaching a bunch of accounts to a campaign with the following code:

$collection = Collection::findOrFail($data['collection']);
$chunks = $collection->accounts->diff($this->campaign->accounts)->pluck('id')->chunk(500);
$chunks->each(fn ($chunk) => $this->campaign->accounts()->attach($chunk));

This unfortunately is generating one insert query for each account for some reason and I don't understand why? The only difference here is that on the first scenario, the relationship is defined without a pivot model while the second does have a pivot model.

Collection.php

    public function accounts(): BelongsToMany
    {
        return $this->belongsToMany(Account::class, 'crm.account_collection')->withTimestamps();
    }

Campaign.php

    public function accounts(): BelongsToMany
    {
        return $this->belongsToMany(Account::class, 'crm.account_campaign')
            ->using(AccountCampaign::class)
            ->withPivot(['campaign_stage_id', 'sort_order'])
            ->withTimestamps();
    }

Is this the reason or am I missing something?

junior cedar
#

Err so yes, it does appear to be because of the ->using(). I commented out the ->using(AccountCampaign::class) and it did a bulk insert. Is there a way to still use a pivot model and do the bulk insert?