ManyToMany Repeater: Call to a member function subscriptionProducts() on null
I have followed this guide: https://filamentphp.com/docs/3.x/forms/fields/repeater#integrating-with-a-belongstomany-eloquent-relationship but unfortunately no luck.
My models:
subscription:
- id
- name
productSubscription
- id
- product_id
- subscription_id
- price
- quantity
product:
- id
- name
- tax
- default_price
3 Replies
<?php
namespace App\Models;
use App\Enums\SubscriptionPeriod;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Subscription extends Model
{
use HasFactory;
use HasUlids;
protected $fillable = [
'name',
'notes',
'period',
'starts_on',
'ends_on',
];
protected $casts = [
'period' => SubscriptionPeriod::class,
'starts_on' => 'date',
'ends_on' => 'date',
];
protected $with = [
'products',
];
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
public function products(): BelongsToMany
{
return $this->belongsToMany(Product::class)
->using(ProductSubscription::class)
->withPivot(['price', 'quantity']);
}
public function subscriptionProducts(): HasMany
{
return $this->hasMany(ProductSubscription::class);
}
}
<?php
namespace App\Models;
use App\Enums\SubscriptionPeriod;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Subscription extends Model
{
use HasFactory;
use HasUlids;
protected $fillable = [
'name',
'notes',
'period',
'starts_on',
'ends_on',
];
protected $casts = [
'period' => SubscriptionPeriod::class,
'starts_on' => 'date',
'ends_on' => 'date',
];
protected $with = [
'products',
];
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
public function products(): BelongsToMany
{
return $this->belongsToMany(Product::class)
->using(ProductSubscription::class)
->withPivot(['price', 'quantity']);
}
public function subscriptionProducts(): HasMany
{
return $this->hasMany(ProductSubscription::class);
}
}
<?php
namespace App\Models;
use Akaunting\Money\Money;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ProductSubscription extends Pivot
{
protected $fillable = [
'product_id',
'price',
'quantity',
];
public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
public function subscription(): BelongsTo
{
return $this->belongsTo(Subscription::class);
}
}
<?php
namespace App\Models;
use Akaunting\Money\Money;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ProductSubscription extends Pivot
{
protected $fillable = [
'product_id',
'price',
'quantity',
];
public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
public function subscription(): BelongsTo
{
return $this->belongsTo(Subscription::class);
}
}
<?php
namespace App\Models;
use Akaunting\Money\Money;
use App\Enums\ProductTax;
use App\Enums\ProductType;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Product extends Model
{
use HasFactory;
use HasUlids;
protected $fillable = [
'name',
'type',
'tax',
'price',
];
protected $casts = [
'type' => ProductType::class,
'tax' => ProductTax::class,
];
public function tenant(): BelongsTo
{
return $this->belongsTo(Tenant::class);
}
public function subscriptions(): BelongsToMany
{
return $this->belongsToMany(Subscription::class)
->using(ProductSubscription::class);
}
}
<?php
namespace App\Models;
use Akaunting\Money\Money;
use App\Enums\ProductTax;
use App\Enums\ProductType;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Product extends Model
{
use HasFactory;
use HasUlids;
protected $fillable = [
'name',
'type',
'tax',
'price',
];
protected $casts = [
'type' => ProductType::class,
'tax' => ProductTax::class,
];
public function tenant(): BelongsTo
{
return $this->belongsTo(Tenant::class);
}
public function subscriptions(): BelongsToMany
{
return $this->belongsToMany(Subscription::class)
->using(ProductSubscription::class);
}
}
<?php
namespace App\Filament\AppPanel\Resources\CustomerResource\Pages;
use App\Filament\AppPanel\Resources\CustomerResource;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Resources\Pages\ManageRelatedRecords;
class ManageCustomerSubscriptions extends ManageRelatedRecords
{
protected static string $resource = CustomerResource::class;
protected static string $relationship = 'subscriptions';
protected static ?string $navigationIcon = 'heroicon-o-document-duplicate';
protected static ?string $navigationLabel = 'Abonnementen';
protected static ?string $breadcrumb = 'Abonnementen';
public function getTitle(): string
{
return $this->record->name;
}
public function form(Form $form): Form
{
return $form
->schema([
Repeater::make('subscriptionProducts')
->relationship()
->schema([
Select::make('product_id')
->relationship('product', 'name')
->required(),
]),
]);
}
//...
<?php
namespace App\Filament\AppPanel\Resources\CustomerResource\Pages;
use App\Filament\AppPanel\Resources\CustomerResource;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Resources\Pages\ManageRelatedRecords;
class ManageCustomerSubscriptions extends ManageRelatedRecords
{
protected static string $resource = CustomerResource::class;
protected static string $relationship = 'subscriptions';
protected static ?string $navigationIcon = 'heroicon-o-document-duplicate';
protected static ?string $navigationLabel = 'Abonnementen';
protected static ?string $breadcrumb = 'Abonnementen';
public function getTitle(): string
{
return $this->record->name;
}
public function form(Form $form): Form
{
return $form
->schema([
Repeater::make('subscriptionProducts')
->relationship()
->schema([
Select::make('product_id')
->relationship('product', 'name')
->required(),
]),
]);
}
//...
Call to a member function subscriptionProducts() on null
I thought it might have something to do with ulids, so I temporarily used normal ids everywhere in my app. This did not change the resultHey did you manage to find a solution to this? I'm getting the same error
No I did not, ended up using a relation manager instead :/