F
Filament16mo ago
Avriant

multiple() fields on /create return null

Full Disclosure: very inexperienced with Filament and php in general. Began this project a while ago in my free time with V2+Companies plugin and plan to finish it before going for V3. Trying to save an array of tag IDs as JSON, fields not registered (first time implementing Multiple() Filament logic). Any advice would be much appreciated 🙂 Error:
SQLSTATE[HY000]: General error: 1364 Field 'tenyi' doesn't have a default value

insert into
company_interiors (
shiyou_henkou,
company_id,
updated_at,
created_at
)
values
(1, 2, 2023 -08 -29 07: 18: 37, 2023 -08 -29 07: 18: 37)
SQLSTATE[HY000]: General error: 1364 Field 'tenyi' doesn't have a default value

insert into
company_interiors (
shiyou_henkou,
company_id,
updated_at,
created_at
)
values
(1, 2, 2023 -08 -29 07: 18: 37, 2023 -08 -29 07: 18: 37)
Migration
Schema::create('company_interiors', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(\App\Models\Company::class, 'company_id');
$table->json('tenyi');
$table->json('yuka');
$table->json('kabe');
$table->json('kengu');
$table->boolean('shiyou_henkou');
$table->timestamps();
Schema::create('company_interiors', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(\App\Models\Company::class, 'company_id');
$table->json('tenyi');
$table->json('yuka');
$table->json('kabe');
$table->json('kengu');
$table->boolean('shiyou_henkou');
$table->timestamps();
Model
Model
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class CompanyInterior extends Model
{
use HasFactory;

protected $table = 'company_interiors';

protected $casts = [
'tenyi' => 'array',
'yuka' => 'array',
'kabe' => 'array',
'kengu' => 'array',
'shiyou_henkou' => 'boolean'
];

protected $fillable = [
'company_id',
'tenyi',
'yuka',
'kabe',
'kengu',
'shiyou_henkou'
];

public function types(): BelongsToMany
{
return $this->belongsToMany(InteriorProvider::class);
}
}
Model
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class CompanyInterior extends Model
{
use HasFactory;

protected $table = 'company_interiors';

protected $casts = [
'tenyi' => 'array',
'yuka' => 'array',
'kabe' => 'array',
'kengu' => 'array',
'shiyou_henkou' => 'boolean'
];

protected $fillable = [
'company_id',
'tenyi',
'yuka',
'kabe',
'kengu',
'shiyou_henkou'
];

public function types(): BelongsToMany
{
return $this->belongsToMany(InteriorProvider::class);
}
}
12 Replies
Avriant
AvriantOP16mo ago
Resource
class CompanyInteriorResource extends Resource
{
protected static ?string $model = CompanyInterior::class;

protected static ?string $modelLabel = '内装';

protected static ?string $navigationIcon = 'heroicon-o-collection';

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('tenyi')
->relationship('types', 'provider')
->preload()
->searchable()
->multiple()
->label('天井メーカー')
->required(),
Forms\Components\Select::make('yuka')
->relationship('types', 'provider')
->preload()
->searchable()
->multiple()
->label('床メーカー')
->required(),
Forms\Components\Select::make('kabe')
->relationship('types', 'provider')
->preload()
->searchable()
->multiple()
->label('壁メーカー')
->required(),
Forms\Components\Select::make('kengu')
->relationship('types', 'provider')
->preload()
->searchable()
->multiple()
->label('建具')
->required(),
Forms\Components\Toggle::make('shiyou_henkou')
->label('仕様変更')
->required(),
]);
}

//To be continued
class CompanyInteriorResource extends Resource
{
protected static ?string $model = CompanyInterior::class;

protected static ?string $modelLabel = '内装';

protected static ?string $navigationIcon = 'heroicon-o-collection';

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Select::make('tenyi')
->relationship('types', 'provider')
->preload()
->searchable()
->multiple()
->label('天井メーカー')
->required(),
Forms\Components\Select::make('yuka')
->relationship('types', 'provider')
->preload()
->searchable()
->multiple()
->label('床メーカー')
->required(),
Forms\Components\Select::make('kabe')
->relationship('types', 'provider')
->preload()
->searchable()
->multiple()
->label('壁メーカー')
->required(),
Forms\Components\Select::make('kengu')
->relationship('types', 'provider')
->preload()
->searchable()
->multiple()
->label('建具')
->required(),
Forms\Components\Toggle::make('shiyou_henkou')
->label('仕様変更')
->required(),
]);
}

//To be continued
Resource pt2
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TagsColumn::make('tenyi'),
Tables\Columns\TagsColumn::make('yuka'),
Tables\Columns\TagsColumn::make('kabe'),
Tables\Columns\TagsColumn::make('kengu'),
Tables\Columns\ToggleColumn::make('shiyou_henkou')
->boolean(),
Tables\Columns\TextColumn::make('created_at')
->dateTime(),
Tables\Columns\TextColumn::make('updated_at')
->dateTime(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}

public static function getRelations(): array
{
return [
//
];
}

public static function getPages(): array
{
return [
'index' => Pages\ListCompanyInteriors::route('/'),
'create' => Pages\CreateCompanyInterior::route('/create'),
'edit' => Pages\EditCompanyInterior::route('/{record}/edit'),
];
}
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TagsColumn::make('tenyi'),
Tables\Columns\TagsColumn::make('yuka'),
Tables\Columns\TagsColumn::make('kabe'),
Tables\Columns\TagsColumn::make('kengu'),
Tables\Columns\ToggleColumn::make('shiyou_henkou')
->boolean(),
Tables\Columns\TextColumn::make('created_at')
->dateTime(),
Tables\Columns\TextColumn::make('updated_at')
->dateTime(),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}

public static function getRelations(): array
{
return [
//
];
}

public static function getPages(): array
{
return [
'index' => Pages\ListCompanyInteriors::route('/'),
'create' => Pages\CreateCompanyInterior::route('/create'),
'edit' => Pages\EditCompanyInterior::route('/{record}/edit'),
];
}
}
Dennis Koch
Dennis Koch16mo ago
You are using ->relationship('types', 'provider') on all your Selects which means Filament saves that data to your relationship and not a column. That's why it's empty. If you don't want to save to the relationship, just use ->options(fn () => "query your relation data")
Avriant
AvriantOP16mo ago
🤯 Will try that right now, thank you so much! It worked!
Avriant
AvriantOP16mo ago
Avriant
AvriantOP16mo ago
Avriant
AvriantOP16mo ago
Hope this solution (my code) is not ridiculous
Dennis Koch
Dennis Koch16mo ago
Looks good to me.
Avriant
AvriantOP16mo ago
Now question becomes, how do I display corresponding label names on Table view instead of ids Thanks! I'll mark this one as resolved
Dennis Koch
Dennis Koch16mo ago
If you'd use a relation, you could just do kengu.provider. But since you use JSON, you need to format the data yourself. You could do this via something like this: ->formatStateUsing(fn ($state) => InteriorProvider::find($state)->provider)
Avriant
AvriantOP16mo ago
I'm confused to be honest. You've mentioned that
->relationship('types', 'provider')
->relationship('types', 'provider')
saves it "to my relationship?" I thought this line of code is supposed to just load an associated data from a table using a function specified in ORM. I'm trying to find where I learned this piece of code (trying to search V2 docs for -> relationship), but can't seem to find it... If relation is no longer there (because I'm not using that line I suppose?), how come I get proper ID association with corresponding name for specific provider? (e.g. provider with id 2 = Panasonic if I go to /edit screen). Sorry if that's a somewhat banal question 🙂
Dennis Koch
Dennis Koch16mo ago
Was that answered by my last answer?
Avriant
AvriantOP16mo ago
I understand your solution, but I'm trying to understand the logic behind it. Don't waste your time — will try to figure it out on my own!
Want results from more Discord servers?
Add your server