Certainly! Here's how you can approach importing relationships with additional pivot values in Laravel, specifically for your Work ↔ Account many-to-many with author_role in the pivot.
Steps:
- Read the CSV and parse it row by row.
- Find the Work using the
work_number(e.g.,W-47EZC18X). - Find the Account using the
account_number(e.g.,A-TPWQEW1Q). - Attach the Account to the Work with the
author_roleas pivot value.
Below is an example method you might put in a custom import command or job:
use App\Models\Work;
use App\Models\Account;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
// assuming $data is an array of rows from your csv, each with 'work_id', 'account_id', 'author_role'
// If you're using something like Laravel Excel, this will come naturally
foreach ($data as $row) {
// Find Work by work_number
$work = Work::where('work_number', $row['Work ID'])->first();
if (!$work) {
Log::warning("Work not found: " . $row['Work ID']);
continue;
}
// Find Account by account_number
$account = Account::where('account_number', $row['Account ID'])->first();
if (!$account) {
Log::warning("Account not found: " . $row['Account ID']);
continue;
}
// Attach with pivot (prevents duplicates by default if entries are unique)
$work->authors()->syncWithoutDetaching([
$account->id => ['author_role' => $row['Author Role']]
]);
}
Key Points:
syncWithoutDetachingensures you don’t overwrite existing authors for the work, and it also updates the pivot value if the combination already exists.- Replace direct array access (
$row['Work ID']) with trimmed/lowercased indices if your CSV headings vary. - Logging is optional but recommended for debugging missing records.
If using Filament Importers
If you are customizing a Filament resource importer, you’d typically override the logic in your importer:
public static function resolveRecord(array $row): ?Model
{
$work = Work::where('work_number', $row['Work ID'])->first();
$account = Account::where('account_number', $row['Account ID'])->first();
if ($work && $account) {
$work->authors()->syncWithoutDetaching([
$account->id => ['author_role' => $row['Author Role']]
]);
}
// You can choose to return $work or null, depending on Filament's expectations
return $work;
}
Summary
- Find both Work and Account by their human-readable keys.
- Attach the account to the work with the pivot value, using
syncWithoutDetaching. - For Filament or other importer systems, override the appropriate record/relationship resolution method.
You do NOT need to manually insert into the pivot table; Eloquent relationships handle this.
Let me know if you need a more concrete example for your specific importer tool or more context on the CSV parsing!