BelongsToMany Relationship Cast Problem on Edit Record

Hi, this is my first time asking the question on this forum. So i hope i will able to provide all the details that are required. Let me first explain what issue i am having. I have a relationship-manager UsersRelationManager for ProjectResource The data displayed on table for Special CPI is properly casted using MoneyCast. (Storing 650 in database and displaying $6.50 on table) But when i click on edit record Special CPI value is 650 instead of 6.50. The Cast is working properly on the ProjectResource everywhere. Only giving error on relationship.
I hope i am able to explain it properly, let me know if you need more details. And thank you in advance 🙂 Attached the 2nd image (for edit Record) in next post.
No description
3 Replies
CodingAuthority
CodingAuthorityOP12mo ago
MoneyCast code
public function get($model, string $key, $value, array $attributes): float
{
return round(floatval($value) / 100, precision: 2);
}

public function set($model, string $key, $value, array $attributes): float
{
return round(floatval($value) * 100);
}
public function get($model, string $key, $value, array $attributes): float
{
return round(floatval($value) / 100, precision: 2);
}

public function set($model, string $key, $value, array $attributes): float
{
return round(floatval($value) * 100);
}
So i have 3 tables in my app. Project Table
Schema::create('projects', function (Blueprint $table) {
$table->id();
$table->string('name', 500);
$table->string('pid', 500)->nullable();
$table->string('status')->default('paused');
$table->integer('cpi')->nullable();
$table->timestamps();
});
Schema::create('projects', function (Blueprint $table) {
$table->id();
$table->string('name', 500);
$table->string('pid', 500)->nullable();
$table->string('status')->default('paused');
$table->integer('cpi')->nullable();
$table->timestamps();
});
User Table
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
ProjectUser Pivot Table
Schema::create('project_user', function (Blueprint $table) {
$table->id('pivot_id');
$table->foreignId('project_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('special_status')->default('paused');
$table->integer('special_cpi')->nullable();
$table->timestamps();
});
Schema::create('project_user', function (Blueprint $table) {
$table->id('pivot_id');
$table->foreignId('project_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('special_status')->default('paused');
$table->integer('special_cpi')->nullable();
$table->timestamps();
});
No description
CodingAuthority
CodingAuthorityOP12mo ago
Project Model has Cast and BelongsToMany Relationship
class Project extends Model
{
protected $casts = [
'status' => ProjectStatus::class,
'cpi' => MoneyCast::class,
];

public function users(): BelongsToMany
{
return $this->belongsToMany(User::class)
->using(ProjectUser::class)
->withPivot('pivot_id', 'special_status', 'special_cpi')
->withTimestamps();
}
}
class Project extends Model
{
protected $casts = [
'status' => ProjectStatus::class,
'cpi' => MoneyCast::class,
];

public function users(): BelongsToMany
{
return $this->belongsToMany(User::class)
->using(ProjectUser::class)
->withPivot('pivot_id', 'special_status', 'special_cpi')
->withTimestamps();
}
}
User Model has BelongsToMany Relationship
class User extends Authenticatable
{
public function projects(): BelongsToMany
{
return $this->belongsToMany(Project::class)
->using(ProjectUser::class)
->withPivot('pivot_id', 'special_status', 'special_cpi')
->withTimestamps();
}
}
class User extends Authenticatable
{
public function projects(): BelongsToMany
{
return $this->belongsToMany(Project::class)
->using(ProjectUser::class)
->withPivot('pivot_id', 'special_status', 'special_cpi')
->withTimestamps();
}
}
ProjectUser Model with Casts and other table related data
class ProjectUser extends Pivot
{
protected $primaryKey = 'pivot_id';
public $incrementing = true;
protected $table = 'project_user';
protected $casts = [
'special_status' => ProjectStatus::class,
'special_cpi' => MoneyCast::class,
];
}
class ProjectUser extends Pivot
{
protected $primaryKey = 'pivot_id';
public $incrementing = true;
protected $table = 'project_user';
protected $casts = [
'special_status' => ProjectStatus::class,
'special_cpi' => MoneyCast::class,
];
}
Than i have UsersRelationManager for ProjectResource
class UsersRelationManager extends RelationManager
{
protected static string $relationship = 'users';

public function isReadOnly(): bool
{
return false;
}

public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('email')
->required()
->maxLength(255),
Forms\Components\TextInput::make('special_cpi')
->required()
->numeric()
->inputMode('decimal'),
Forms\Components\Select::make('special_status')
->options(ProjectStatus::class)
->required()
]);
}

public function table(Table $table): Table
{
return $table
->recordTitleAttribute('email')
->columns([
Tables\Columns\TextColumn::make('email'),
Tables\Columns\TextColumn::make('special_cpi')
->money('USD'),
])
->filters([
//
])
->headerActions([
Tables\Actions\CreateAction::make(),
Tables\Actions\AttachAction::make(),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DetachAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DetachBulkAction::make(),
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
}
class UsersRelationManager extends RelationManager
{
protected static string $relationship = 'users';

public function isReadOnly(): bool
{
return false;
}

public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('email')
->required()
->maxLength(255),
Forms\Components\TextInput::make('special_cpi')
->required()
->numeric()
->inputMode('decimal'),
Forms\Components\Select::make('special_status')
->options(ProjectStatus::class)
->required()
]);
}

public function table(Table $table): Table
{
return $table
->recordTitleAttribute('email')
->columns([
Tables\Columns\TextColumn::make('email'),
Tables\Columns\TextColumn::make('special_cpi')
->money('USD'),
])
->filters([
//
])
->headerActions([
Tables\Actions\CreateAction::make(),
Tables\Actions\AttachAction::make(),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DetachAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DetachBulkAction::make(),
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
}
That's all. I am really sorry for sending more than few messages, discord limits the max characters
bogus
bogus11mo ago
Hi, @CodingAuthority have you figured out how to solve this problem? The most interesting thing is that in my case, when writing, cast works, but when reading for editing it does not =/ here not a solution, but an interesting workaround https://www.youtube.com/watch?v=0vhAfwr1WRk
Filament Daily
YouTube
Filament Macros: Add Methods To Columns and Inputs
Example of a method to be added to your TextInput, TextColumn and similar components. Source: https://github.com/andrewdwallo/erpsaas/blob/2.x/app/Providers/AppServiceProvider.php More Filament examples on our website: https://filamentexamples.com
Want results from more Discord servers?
Add your server