To address the issue of nested attributes and terms not being saved in the attribute_product_variation table, you need to ensure that the nested repeater data is being properly handled and saved. Here’s a step-by-step solution:
-
Ensure Relationships are Defined Correctly: Make sure your models have the correct relationships defined. From your provided code, it looks like you have set up the relationships correctly.
-
Update the Product Resource: You need to ensure that the nested repeater data is being saved correctly. This involves handling the saving process in the
ProductResourceclass. -
Handle Saving Nested Data: You need to override the
savedmethod in yourProductResourceto handle saving the nested attributes and terms.
Here’s how you can do it:
ProductResource
use Filament\Forms;
use Filament\Resources\Form;
use Filament\Resources\Resource;
use App\Models\Product;
use App\Models\Attribute;
use App\Models\Term;
class ProductResource extends Resource
{
protected static ?string $model = Product::class;
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Repeater::make('variations')
->relationship('variations')
->schema([
Forms\Components\TextInput::make('market_price')
->numeric()
->required()
->label('Market Price'),
Forms\Components\TextInput::make('sale_price')
->numeric()
->required()
->label('Sale Price'),
Forms\Components\TextInput::make('stock')
->numeric()
->required()
->label('Stock'),
Forms\Components\FileUpload::make('image')
->image()
->disk('public')
->directory('product-images')
->nullable()
->label('Image'),
Forms\Components\Textarea::make('short_description')
->maxLength(65535)
->nullable()
->label('Short Description'),
Forms\Components\Repeater::make('attributes')
->schema([
Forms\Components\Select::make('attribute_id')
->options(Attribute::all()->pluck('name', 'id'))
->required()
->label('Attribute')
->reactive()
->afterStateUpdated(function (callable $set, $state) {
// Update terms based on selected attribute
$terms = Term::where('attribute_id', $state)->pluck('name', 'id');
$set('term_options', $terms); // Update the term options
}),
Forms\Components\Select::make('term_id')
->options(function (callable $get) {
$attributeId = $get('attribute_id');
if ($attributeId) {
return Term::where('attribute_id', $attributeId)->pluck('name', 'id');
}
return [];
})
->required()
->label('Term'),
])
->createItemButtonLabel('Add Attribute'),
])
->createItemButtonLabel('Add Variation'),
]);
}
public static function saved($record, $data)
{
foreach ($data['variations'] as $variationData) {
$variation = $record->variations()->updateOrCreate(
['id' => $variationData['id'] ?? null],
$variationData
);
if (isset($variationData['attributes'])) {
$variation->attributes()->sync([]);
foreach ($variationData['attributes'] as $attributeData) {
$variation->attributes()->attach($attributeData['attribute_id'], ['term_id' => $attributeData['term_id']]);
}
}
}
}
}
Explanation:
-
Form Schema:
- The form schema defines the structure of the form, including the nested repeaters for variations and attributes.
-
Saved Method:
- The
savedmethod is overridden to handle the saving of nested attributes and terms. - For each variation, it updates or creates the variation record.
- It then syncs the attributes for each variation, ensuring that the
attribute_product_variationtable is updated with the correctattribute_idandterm_id.
- The
This should ensure that your nested attributes and terms are saved correctly in the attribute_product_variation table.