Retriving album_id from a relationships - Select::make('album:id)

Hi guys, I'm a noob and I'm stucked with this thing... I actually have a double problem with this. Hope someone can help, i paste some code here below:
25 Replies
Lux Auram
Lux AuramOP15mo ago
So I have the filament User who can have many photos and albums and albums can have multiple photo as well. When I create a new album I associate it to an user (with a modal) using this:
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make()
->mutateFormDataUsing(function (array $data): array {
$data['user_id'] = auth()->id();

return $data;
}),
];
}
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make()
->mutateFormDataUsing(function (array $data): array {
$data['user_id'] = auth()->id();

return $data;
}),
];
}
Right now, for the "photo situation" I have to link the id of the album and the id of the user to a photo. For the user was similar as I did before so THAT'S FINE. I'm having some trouble with the album. -FIRST OF ALL: I select the album to pick up (to associate to a photo) whit this:
Select::make('album_id')
->relationship('album', 'title')
->searchable()
->preload()
->createOptionForm([
TextInput::make('key')
->label('Posizione n.')
->required()
->numeric()
->inputMode('decimal'),
TextInput::make('title')
->label('Titolo Album')
->required()
->maxLength(60),
TextInput::make('description')
->label('Note')
->columnSpanFull(),
Toggle::make('active')
->label("Vuoi Pubblicare l'Album?")
])
Select::make('album_id')
->relationship('album', 'title')
->searchable()
->preload()
->createOptionForm([
TextInput::make('key')
->label('Posizione n.')
->required()
->numeric()
->inputMode('decimal'),
TextInput::make('title')
->label('Titolo Album')
->required()
->maxLength(60),
TextInput::make('description')
->label('Note')
->columnSpanFull(),
Toggle::make('active')
->label("Vuoi Pubblicare l'Album?")
])
-SECOND OF ALL: I got stucked. Cause right now, as you can see, I can create really easily an album BUUUUUUT I absolutely can't associate none 'user_id' (cause If you open the modal to create a new album it ask for 'user_id' as well) neither I'm able to associate an 'album_id' to the new album I'm creating... I've tried to find something on documentation but nothing is working and I'm a real noob... PLS HELP 😭
Dennis Koch
Dennis Koch15mo ago
Sorry, I don't get the issue.
UUUUUUT I absolutely can't associate none 'user_id' (cause If you open the modal to create a new album it ask for 'user_id' as well)
Can you show this? Where does it ask for the ID? Or is it an error from the DB? You didn't specify a user_id inside createOptionForm() and it's a different Action than your first one. You can adjust the Action: https://filamentphp.com/docs/3.x/forms/fields/select#customizing-the-select-action-objects
neither I'm able to associate an 'album_id' to the new album I'm creating... I've tried to find something on documentation but nothing is working and I'm a real noob...
Can you explain this more? Also a DB issue? Or something else?
Lux Auram
Lux AuramOP15mo ago
Hi ty for answering. It's not a db issue, I think it's just because i'm a noob. So as I said, when i create a new album it has to be associated to an user, right? That's why I have done this in the AlbumResource/Pages/ManageAlbums
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make()
->mutateFormDataUsing(function (array $data): array {
$data['user_id'] = auth()->id();

return $data;
}),
];
}
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make()
->mutateFormDataUsing(function (array $data): array {
$data['user_id'] = auth()->id();

return $data;
}),
];
}
The problem is when I try to do the same thing for the Photos upload... If I just had to link a photo to an user is easy, because I have in PhotoResource/Pages/CreatePhoto this code here:
protected function mutateFormDataBeforeCreate(array $data): array
{
$data['user_id'] = auth()->id();

return $data;
}
protected function mutateFormDataBeforeCreate(array $data): array
{
$data['user_id'] = auth()->id();

return $data;
}
BUT in the PhotoResource I have a Select that give me the possiblity to associate the photo to an album (TOTALLY FIND) or to create a new album in the same page of the photo uploading (BIG PROBLEM) because here, during THIS SPECIFIC MODAL I really dunno how to link the user_id to the new album I'm creating, because this "modal-in-modal" don't use this code here:
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make()
->mutateFormDataUsing(function (array $data): array {
$data['user_id'] = auth()->id();

return $data;
}),
];
}
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make()
->mutateFormDataUsing(function (array $data): array {
$data['user_id'] = auth()->id();

return $data;
}),
];
}
So i'm not getting the user who create the album FURTHERMORE if I'm using this
Select::make('album_id')
->relationship('album', 'title')
Select::make('album_id')
->relationship('album', 'title')
to retrieve the album title through its id, AT THE END, i'm not getting the id saved but received a NULL property on the database BTW i dunno how to add this option to save in this specific case the album_id and the user_id with this code here I think it's pretty easy but I'm noob af Hope this is more clear :/
Dennis Koch
Dennis Koch15mo ago
Try a combination of ->createOptionAction() and ->mutateFormDataUsing()
Select::make()
->createOptionForm(....)
->createOptionAction(
fn ($action) => $action->mutateFormDataUsing(function (array $data): array {
$data['user_id'] = auth()->id();

return $data;
}),
Select::make()
->createOptionForm(....)
->createOptionAction(
fn ($action) => $action->mutateFormDataUsing(function (array $data): array {
$data['user_id'] = auth()->id();

return $data;
}),
Try removing the ->relationship() or make the field nullable, because that saves after the record was created. You can use ->options(fn () => Album::pluck('title', 'id)) instead
Lux Auram
Lux AuramOP15mo ago
Select field [data.album_id] must have a [createOptionUsing()] closure set.
Select field [data.album_id] must have a [createOptionUsing()] closure set.
What this mean? T_T
Dennis Koch
Dennis Koch15mo ago
Might be possible, that this is only available in combination with ->relationship() 🤔
Lux Auram
Lux AuramOP15mo ago
Btw, using this with an existing album doesn't give me the album_id in the database... I'm just gettin the classi user_id how do I solve all this? T_T
Dennis Koch
Dennis Koch15mo ago
See my answer above. You probably need to make the database column nullable
Lux Auram
Lux AuramOP15mo ago
Which one?
Dennis Koch
Dennis Koch15mo ago
The "make the field nullable" answer.
Lux Auram
Lux AuramOP15mo ago
No dude... ofc... I mean which column should be nullable? Cause if u mean the 'album_id' and 'user_id' they are already nullable
Dennis Koch
Dennis Koch15mo ago
Ah right, you already wrote that you get null on DB, sorry 🙈 Hmm, weird one. Can you share the Photo model with the album relationship?
Lux Auram
Lux AuramOP15mo ago
Sure: Photo Model:
protected $table = 'photos';

protected $primaryKey = 'id';

protected $fillable = [
'user_id',
'key',
'image',
'title',
'description',
'active',
'published_at',
];

protected $casts = [
'published_at' => 'datetime'
];

public function album(): BelongsTo {
return $this->belongsTo(Album::class);
}

public function user(): HasOne {
return $this->hasOne(User::class, 'user_id', 'id');
}
protected $table = 'photos';

protected $primaryKey = 'id';

protected $fillable = [
'user_id',
'key',
'image',
'title',
'description',
'active',
'published_at',
];

protected $casts = [
'published_at' => 'datetime'
];

public function album(): BelongsTo {
return $this->belongsTo(Album::class);
}

public function user(): HasOne {
return $this->hasOne(User::class, 'user_id', 'id');
}
Photo Migration:
public function up(): void
{
if(!Schema::hasTable('photos')){
Schema::create('photos', function (Blueprint $table) {
$table->id()->unique();
$table->foreignIdFor(Album::class)->nullable()->onDelete('set null')->constrained();
$table->foreignIdFor(User::class)->nullable()->onDelete('set null')->constrained();
$table->integer('key');
$table->string('image', 2048);
$table->string('title', 255)->nullable();
$table->longText('description')->nullable();
$table->boolean('active')->default(0);
$table->datetime('published_at')->required();
$table->timestamps();
});
}
}
public function up(): void
{
if(!Schema::hasTable('photos')){
Schema::create('photos', function (Blueprint $table) {
$table->id()->unique();
$table->foreignIdFor(Album::class)->nullable()->onDelete('set null')->constrained();
$table->foreignIdFor(User::class)->nullable()->onDelete('set null')->constrained();
$table->integer('key');
$table->string('image', 2048);
$table->string('title', 255)->nullable();
$table->longText('description')->nullable();
$table->boolean('active')->default(0);
$table->datetime('published_at')->required();
$table->timestamps();
});
}
}
Album Model:
protected $primaryKey = 'id';

protected $fillable = [
'user_id',
'key',
'title',
'description',
'active',
'published_at',
];

protected $casts = [
'published_at' => 'datetime'
];

public function photos(): HasMany {
return $this->hasMany(Photo::class);
}

public function user(): HasOne {
return $this->hasOne(User::class, 'user_id', 'id');
}
protected $primaryKey = 'id';

protected $fillable = [
'user_id',
'key',
'title',
'description',
'active',
'published_at',
];

protected $casts = [
'published_at' => 'datetime'
];

public function photos(): HasMany {
return $this->hasMany(Photo::class);
}

public function user(): HasOne {
return $this->hasOne(User::class, 'user_id', 'id');
}
Album Migration:
public function up(): void
{
if(!Schema::hasTable('albums')){
Schema::create('albums', function (Blueprint $table) {
$table->id()->unique();
$table->foreignIdFor(User::class, 'user_id');
$table->foreignId('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('key');
$table->string('title', 255)->required();
$table->longText('description')->nullable();
$table->boolean('active')->default(0);
$table->datetime('published_at')->required();
$table->timestamps();
});
}
}
public function up(): void
{
if(!Schema::hasTable('albums')){
Schema::create('albums', function (Blueprint $table) {
$table->id()->unique();
$table->foreignIdFor(User::class, 'user_id');
$table->foreignId('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('key');
$table->string('title', 255)->required();
$table->longText('description')->nullable();
$table->boolean('active')->default(0);
$table->datetime('published_at')->required();
$table->timestamps();
});
}
}
Dennis Koch
Dennis Koch15mo ago
This is in the AlbumResource form, right?
Lux Auram
Lux AuramOP15mo ago
These are the Models from Model. I Past the AlbumResource as well (but the problem is in the PhotoResource)
Dennis Koch
Dennis Koch15mo ago
Sorry, I meant to PhotoResource. The code at the beginning was the form() method, right`?
Lux Auram
Lux AuramOP15mo ago
PhotoResource:
return $form
->schema([
TextInput::make('key')
->label('Posizione n.')
->required()
->numeric()
->inputMode('decimal'),
Forms\Components\FileUpload::make('image')
->label('Carica Foto')
->image()
->imageEditor()
->imageEditorAspectRatios([
null,
'16:9',
'4:3',
'1:1',
])
->required(),
TextInput::make('title')
->label('Titolo Foto')
->maxLength(2048),
Textarea::make('description')
->label('Note')
->columnSpanFull(),
Forms\Components\Toggle::make('active')
->label('Vuoi Pubblicare la Foto?'),
Forms\Components\DateTimePicker::make('published_at')
->label('Data Pubblicazione')
->required(),
return $form
->schema([
TextInput::make('key')
->label('Posizione n.')
->required()
->numeric()
->inputMode('decimal'),
Forms\Components\FileUpload::make('image')
->label('Carica Foto')
->image()
->imageEditor()
->imageEditorAspectRatios([
null,
'16:9',
'4:3',
'1:1',
])
->required(),
TextInput::make('title')
->label('Titolo Foto')
->maxLength(2048),
Textarea::make('description')
->label('Note')
->columnSpanFull(),
Forms\Components\Toggle::make('active')
->label('Vuoi Pubblicare la Foto?'),
Forms\Components\DateTimePicker::make('published_at')
->label('Data Pubblicazione')
->required(),
Select::make('album_id')
->options(Album::query()->pluck('title', 'id'))
->required()
->searchable()
->preload()
->createOptionForm([
TextInput::make('key')
->label('Posizione n.')
->required()
->numeric()
->inputMode('decimal'),
TextInput::make('title')
->label('Titolo Album')
->required()
->maxLength(60),
TextInput::make('description')
->label('Note')
->columnSpanFull(),
Toggle::make('active')
->label("Vuoi Pubblicare l'Album?")
])
->createOptionUsing(function (array $data, Album $record): void {
$record->author()->associate($data['album_id']);
$record->save();
})
}
Select::make('album_id')
->options(Album::query()->pluck('title', 'id'))
->required()
->searchable()
->preload()
->createOptionForm([
TextInput::make('key')
->label('Posizione n.')
->required()
->numeric()
->inputMode('decimal'),
TextInput::make('title')
->label('Titolo Album')
->required()
->maxLength(60),
TextInput::make('description')
->label('Note')
->columnSpanFull(),
Toggle::make('active')
->label("Vuoi Pubblicare l'Album?")
])
->createOptionUsing(function (array $data, Album $record): void {
$record->author()->associate($data['album_id']);
$record->save();
})
}
Dennis Koch
Dennis Koch15mo ago
And this also doesn't save album_id for Photo? 🤔 Or is it just combined with ->relationship()?
Lux Auram
Lux AuramOP15mo ago
yep it doesn't nor If I create the album in the Photo page nor if I select an existing one.
Dennis Koch
Dennis Koch15mo ago
What if you remove all methods from the Select apart from ->options() Select::make('album_id')->options(...)
Lux Auram
Lux AuramOP15mo ago
Yeah i just tried... If I just have the album id to show up (with preload()) they don't show up it's like i'm no getting the album ids at all... it shows up the name but if I decide to see just ids they don't show up
Dennis Koch
Dennis Koch15mo ago
Btw. the album_id issue might be because it is not fillable. Can you share the code you used?
Lux Auram
Lux AuramOP15mo ago
I try to :fresh and I let u know Jesus it worked -.- it was just the fillable problem.. I mean I've tried with an existing album and I'm getting the link both with user_id and album_id now I try to create a new one (from the PhotoResource)
App\Filament\Resources\PhotoResource::App\Filament\Resources\{closure}(): Argument #2 ($record) must be of type App\Models\Album, null given, called in
App\Filament\Resources\PhotoResource::App\Filament\Resources\{closure}(): Argument #2 ($record) must be of type App\Models\Album, null given, called in
I'm receiving this because of this:
->createOptionUsing(function (array $data, Album $record): void {
$record->author()->associate($data['album_id']);
$record->save();
})
->createOptionUsing(function (array $data, Album $record): void {
$record->author()->associate($data['album_id']);
$record->save();
})
Dennis Koch
Dennis Koch15mo ago
There is no Album $record in a CREATE option.
Lux Auram
Lux AuramOP15mo ago
Occhei... so... I don't knwo... I mean this last piece of code was just copy/pasted to see if something changed xD Is it correct? Do I have to keep it? And if yes how do I create this func in the create page? like literally. (Sorry for the bothering dude but i'm noob af. Like a lot. I'm from fashion retail and I've just swapped my life)
Want results from more Discord servers?
Add your server