Certainly! Here's how you can approach building an importer for a MorphTo relationship using Filament in Laravel.
Understanding the Problem
- Customer has an Address relationship, where
Addressis morphed to various models (MorphTo). - You want to import data (presumably from CSV/Excel) such that addresses are correctly associated with the customers via the MorphTo.
Solution Overview
When importing, you need to ensure:
- The
addressable_idandaddressable_typefields are set correctly in theaddressestable. - The import process knows which model (in this case
Customer) the address belongs to.
Assuming your addresses table looks like:
Schema::create('addresses', function (Blueprint $table) {
$table->id();
$table->morphs('addressable'); // addressable_id, addressable_type
$table->string('address');
// ... other fields
});
And your Customer model:
public function addresses()
{
return $this->morphMany(Address::class, 'addressable');
}
Example Importer Using maatwebsite/excel with Filament
Let's use maatwebsite/excel, which is a common package for importing/excel data in Laravel ecosystems. If you're using Filament Excel, it leverages this under the hood.
AddressImport.php:
namespace App\Imports;
use App\Models\Customer;
use App\Models\Address;
use Maatwebsite\Excel\Row;
use Maatwebsite\Excel\Concerns\OnEachRow;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class AddressImport implements OnEachRow, WithHeadingRow
{
public function onRow(Row $row)
{
$row = $row->toArray();
// Lookup Customer
$customer = Customer::where('email', $row['customer_email'])->first();
if ($customer) {
$customer->addresses()->create([
'address' => $row['address'],
// add other address fields
]);
}
}
}
Sample CSV Format:
customer_email,address
[email protected],123 Main St
[email protected],456 Elm Ave
When the import runs:
- It locates the customer by email.
- Calls
$customer->addresses()->create([..]), which will automatically set the correctaddressable_idandaddressable_type.
Using Filament Plugin (eg. Filament Excel)
If you're using Filament Excel:
In your Filament Resource for Address, set up the importer similarly.
use App\Imports\AddressImport;
public static function getImportAction(): ImportAction
{
return ImportAction::make()
->importer(AddressImport::class);
}
Tips
- Make sure your input file uniquely identifies the
Customer(or any morphable model). - If addresses can belong to other models, expand logic to check for different model types using a
model_typecolumn in your CSV.
Summary
- In your importer, loop through rows.
- Lookup the related model (
Customer). - Use the relationship (
$customer->addresses()->create()) to create the address. This sets the MorphTo fields automatically.
If you need to support multiple models (not just Customer), add logic to detect addressable_type from your import file.
Let me know if you have a more specific use-case or need to handle multiple morph types!