F
Filament6mo ago
scalar

How to use toggle column to update pivot table?

I have a many-to-many relationship with product, user, and product_user_fav models, and I want to create a favorite toggle column in the products table to update the product_user_fav table (pivot). That is when a user switches the favorite toggle column in the products table if there are no user_id and product_id rows in the Product_user_fav table, a new row is registered in the pivot table, and if there are user_id and product_id, the existing row is removed. How can I do this? Thank you! #user model
id, name
id, name
#product model
id, name

....
public function users()
{
return $this->belongsToMany(User::class, 'product_user_fav');
}
id, name

....
public function users()
{
return $this->belongsToMany(User::class, 'product_user_fav');
}
#product_user_fav model
user_id, product_id
user_id, product_id
#produts table
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title')
->label('Name'),
Tables\Columns\ToggleColumn::make('?')
->label('Fav'),
])
->filters([
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
])
->recordUrl(null);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title')
->label('Name'),
Tables\Columns\ToggleColumn::make('?')
->label('Fav'),
])
->filters([
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
])
->recordUrl(null);
}
No description
42 Replies
jackleblackdev
jackleblackdev6mo ago
Same request
ChesterS
ChesterS6mo ago
you can use the ->updatStateUsing() method to alter the behaviour for example I have the email_verified on my Users table toggle like that
->updateStateUsing(function (User $r) {
$r->email_verified_at === null
? $r->email_verified_at = Carbon::now()
: $r->email_verified_at = null;
$r->save();
}),
->updateStateUsing(function (User $r) {
$r->email_verified_at === null
? $r->email_verified_at = Carbon::now()
: $r->email_verified_at = null;
$r->save();
}),
You can do something similar for your case maybe?
jackleblackdev
jackleblackdev6mo ago
this work on same table, my date are on pivot table like user.posts.0.email_verified
scalar
scalar6mo ago
🤗 🙏 I will try it.
jackleblackdev
jackleblackdev6mo ago
no i want say it didn't work ahah sorry
ChesterS
ChesterS6mo ago
Can you share the whole table? What record is this on? NVM the table is there I don't understand what you're trying to do here. Is this table inside the Product view? So when you're looking at a procuct, you can also select the users that have favorited it?
scalar
scalar6mo ago
Ok, I will share all things, currently, the pivot field is not working in table toggle column. This is Product model
<?php

namespace App\Models;

use App\Models\Scopes\Searchable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Prodcut extends Model
{
use HasFactory;
use Searchable;

protected $fillable = [
'title',
'group_id',
'brand_id',
'unit_id',
];

protected $searchableFields = ['*'];

protected $casts = [
'contracts_types' => 'array',
'public_show_entity' => 'boolean',
'is_fav' => 'boolean',
'travel_scope' => 'array',
'work_schedule' => 'array',
];

public function products()
{
return $this->belongsToMany(Product::class, 'product_user_fav')->withPivot('is_fav');
;
}

}
<?php

namespace App\Models;

use App\Models\Scopes\Searchable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Prodcut extends Model
{
use HasFactory;
use Searchable;

protected $fillable = [
'title',
'group_id',
'brand_id',
'unit_id',
];

protected $searchableFields = ['*'];

protected $casts = [
'contracts_types' => 'array',
'public_show_entity' => 'boolean',
'is_fav' => 'boolean',
'travel_scope' => 'array',
'work_schedule' => 'array',
];

public function products()
{
return $this->belongsToMany(Product::class, 'product_user_fav')->withPivot('is_fav');
;
}

}
This is user model
<?php

namespace App\Models;

use App\Models\Scopes\Searchable;
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;

class User extends Authenticatable implements FilamentUser
{
use Notifiable;
use HasFactory;
use Searchable;

// protected $fillable = ['firstname', 'lastname', 'email', 'password'];

protected $fillable = ['name', 'email', 'password'];

protected $searchableFields = ['*'];

protected $hidden = [
'password',
'remember_token',
'two_factor_secret',
'two_factor_recovery_codes',
];

protected $casts = [
'email_verified_at' => 'datetime',
'two_factor_confirmed_at' => 'datetime',
];


public function roles()
{
return $this->hasManyThrough(Role::class, Group::class);
}

public function products()
{
return $this->belongsToMany(Product::class, 'product_user_fav');
}
}
<?php

namespace App\Models;

use App\Models\Scopes\Searchable;
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;

class User extends Authenticatable implements FilamentUser
{
use Notifiable;
use HasFactory;
use Searchable;

// protected $fillable = ['firstname', 'lastname', 'email', 'password'];

protected $fillable = ['name', 'email', 'password'];

protected $searchableFields = ['*'];

protected $hidden = [
'password',
'remember_token',
'two_factor_secret',
'two_factor_recovery_codes',
];

protected $casts = [
'email_verified_at' => 'datetime',
'two_factor_confirmed_at' => 'datetime',
];


public function roles()
{
return $this->hasManyThrough(Role::class, Group::class);
}

public function products()
{
return $this->belongsToMany(Product::class, 'product_user_fav');
}
}
This is Product resoruce.php to show the products table.
<?php
class ProductResource extends Resource
{
...
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\ToggleColumn::make('is_fav')
->label('Fav')
->toggleable()
->sortable(),
Tables\Columns\TextColumn::make('title')
->label('Title')
->searchable()
->toggleable()
->sortable(),
Tables\Columns\TextColumn::make('group.name')
->label('Entity')
->searchable()
->toggleable()
->sortable(),
Tables\Columns\TextColumn::make('unit.name')
->label('Unit')
->searchable()
->toggleable()
->sortable(),
])
}
...
}
<?php
class ProductResource extends Resource
{
...
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\ToggleColumn::make('is_fav')
->label('Fav')
->toggleable()
->sortable(),
Tables\Columns\TextColumn::make('title')
->label('Title')
->searchable()
->toggleable()
->sortable(),
Tables\Columns\TextColumn::make('group.name')
->label('Entity')
->searchable()
->toggleable()
->sortable(),
Tables\Columns\TextColumn::make('unit.name')
->label('Unit')
->searchable()
->toggleable()
->sortable(),
])
}
...
}
scalar
scalar6mo ago
No description
scalar
scalar6mo ago
When toggling, I got below issue:
scalar
scalar6mo ago
No description
scalar
scalar6mo ago
No description
scalar
scalar6mo ago
How to use is_fav field of pivot table for toggle column?
scalar
scalar6mo ago
No description
ChesterS
ChesterS6mo ago
Ah, so you want the current user to be able to favorite it
scalar
scalar6mo ago
Yes, I want to update the pivot table when toggling
ChesterS
ChesterS6mo ago
Ok, I don't know if there's a better/official way of doing it (using pivot models https://laravel.com/docs/10.x/eloquent-relationships#defining-custom-intermediate-table-models)
scalar
scalar6mo ago
So there are two problems: - how to use the is_fav field for the toggle column. - how to update pivot table when toggling.
ChesterS
ChesterS6mo ago
Give this a try
->updateStateUsing(function (Product $record) {
$record->user()->toggle(auth()->id());
}),
->updateStateUsing(function (Product $record) {
$record->user()->toggle(auth()->id());
}),
also, make sure the syntax for the field is correct. I'm not sure how Filament handles pivot values the ToggleColumn::make('users.pivot.is_fav') might not be enough. You might need to use a getStateUsing() to get what you need
scalar
scalar6mo ago
Here is the filament pivot guide, but it is not working. I will report this packaging issue to the filament team and to all developers. https://filamentphp.com/docs/3.x/panels/resources/relation-managers#listing-with-pivot-attributes
No description
No description
No description
ChesterS
ChesterS6mo ago
actually sorry my bad the toggle will toggle the relationship. You need to update the pivot value
scalar
scalar6mo ago
You are welcome 🙂 Can you introduce a developer to solve this problem? or how to report this issue to Filament team?
ChesterS
ChesterS6mo ago
there are no issues, it can be done you just need to change the code give me a sec
->updateStateUsing(function (Product $record) {
$is_fav= $record
->users
->firstOrFail(fn($u) => $u->is(auth()->user()))
->pivot->is_fav;

$record->users()->syncWithoutDetaching([
auth()->id() => ['is_fav' => ! $is_fav],
]);
})
->getStateUsing(fn(Product $record) => $record->users->first(fn($u) => $u->is(auth()->user()))->pivot->is_fav),
->updateStateUsing(function (Product $record) {
$is_fav= $record
->users
->firstOrFail(fn($u) => $u->is(auth()->user()))
->pivot->is_fav;

$record->users()->syncWithoutDetaching([
auth()->id() => ['is_fav' => ! $is_fav],
]);
})
->getStateUsing(fn(Product $record) => $record->users->first(fn($u) => $u->is(auth()->user()))->pivot->is_fav),
give this a try. The code is ugly but it should work
scalar
scalar6mo ago
Ok got it, thanks.
ChesterS
ChesterS6mo ago
The problem is that each product can have multiple users. You can simplify a lot of this by using some member functions or Attributes on the models. Be careful to not end up with a lot of queries when using relationships (n+1 issue).
scalar
scalar6mo ago
Awesome! It worked! You are a senior developer!!!
ChesterS
ChesterS6mo ago
Haha thanks. Anyway, good luck 👍
scalar
scalar6mo ago
👍 PS: do you know mimul.js?
ChesterS
ChesterS6mo ago
Nope, sorry
scalar
scalar6mo ago
Thanks for your support, plz let me know if you need any help, I will help you immediately! Good luck!
jackleblackdev
jackleblackdev6mo ago
is it possible to get the current column name ? in my case I want multiple pivot in my table
jackleblackdev
jackleblackdev6mo ago
No description
jackleblackdev
jackleblackdev6mo ago
"users.slot.0.pivot.is_approved_supplier"
ChesterS
ChesterS6mo ago
I'm not sure how that would work in a relationship table, I've never used them. Either way, you should be able to modify the code above to work for most cases The hardest part is figuring out how to get to the pivot you need to check/update based on your structure
jackleblackdev
jackleblackdev6mo ago
"Either way, you should be able to modify the code above to work for most cases" maybe if i can access the current column name
ChesterS
ChesterS6mo ago
What do you mean "current column name" ?
jackleblackdev
jackleblackdev6mo ago
"users.slot.0.pivot.is_approved_supplier" to get the index "0" in need
scalar
scalar6mo ago
@jackleblackdev I think you can refer below code to get name:
->getLabel(fn ($record, $column) => $record->name . ' - ' . $column->pivot->role->name)
->getLabel(fn ($record, $column) => $record->name . ' - ' . $column->pivot->role->name)
jackleblackdev
jackleblackdev6mo ago
him I try
scalar
scalar6mo ago
Hi @ChesterS Could you please help me a thing? I'm using SpatieMediaLibraryFileUpload for file uploading, and it works, but it doesn't work when editing. I think it is related to CORS issue. Thank you.
scalar
scalar6mo ago
No description
scalar
scalar6mo ago
No description
ChesterS
ChesterS6mo ago
hmm maybe? it should work on localhost though 🤔 If you open that url, can you see the file?