feat: enhance model attributes with formatted accessors for improved date representation across various models

This commit is contained in:
Yoga Pangestu 2026-04-02 11:55:29 +07:00
parent bccc36ca81
commit aa3bb2ec76
15 changed files with 374 additions and 26 deletions

View File

@ -3,6 +3,7 @@
namespace App\Models; namespace App\Models;
use App\Enums\AssignmentType; use App\Enums\AssignmentType;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -14,10 +15,16 @@
class Assignment extends Model implements HasMedia class Assignment extends Model implements HasMedia
{ {
// --- Traits ---
use HasFactory, InteractsWithMedia, SoftDeletes; use HasFactory, InteractsWithMedia, SoftDeletes;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Casts ---
protected function casts(): array protected function casts(): array
{ {
return [ return [
@ -26,6 +33,25 @@ protected function casts(): array
]; ];
} }
// --- Accessors & Mutators ---
protected function formattedDueDate(): Attribute
{
return Attribute::get(fn () => $this->due_date?->translatedFormat('l, d M Y H:i'));
}
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function assignmentPins(): HasMany public function assignmentPins(): HasMany
{ {
return $this->hasMany(AssignmentPin::class); return $this->hasMany(AssignmentPin::class);

View File

@ -2,13 +2,30 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AssignmentPin extends Model class AssignmentPin extends Model
{ {
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Accessors & Mutators ---
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function assignment(): BelongsTo public function assignment(): BelongsTo
{ {
return $this->belongsTo(Assignment::class); return $this->belongsTo(Assignment::class);

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -10,10 +11,16 @@
class AssignmentSubmission extends Model implements HasMedia class AssignmentSubmission extends Model implements HasMedia
{ {
// --- Traits ---
use HasFactory, InteractsWithMedia; use HasFactory, InteractsWithMedia;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Casts ---
protected function casts(): array protected function casts(): array
{ {
return [ return [
@ -21,6 +28,25 @@ protected function casts(): array
]; ];
} }
// --- Accessors & Mutators ---
protected function formattedSubmittedAt(): Attribute
{
return Attribute::get(fn () => $this->submitted_at?->translatedFormat('l, d M Y H:i'));
}
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function assignment(): BelongsTo public function assignment(): BelongsTo
{ {
return $this->belongsTo(Assignment::class); return $this->belongsTo(Assignment::class);

View File

@ -2,16 +2,35 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AssignmentTarget extends Model class AssignmentTarget extends Model
{ {
// --- Traits ---
use HasFactory; use HasFactory;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Accessors & Mutators ---
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function assignment(): BelongsTo public function assignment(): BelongsTo
{ {
return $this->belongsTo(Assignment::class); return $this->belongsTo(Assignment::class);

View File

@ -2,16 +2,23 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Attendance extends Model class Attendance extends Model
{ {
// --- Traits ---
use HasFactory; use HasFactory;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Casts ---
protected function casts(): array protected function casts(): array
{ {
return [ return [
@ -20,6 +27,30 @@ protected function casts(): array
]; ];
} }
// --- Accessors & Mutators ---
protected function formattedDate(): Attribute
{
return Attribute::get(fn () => $this->date?->translatedFormat('l, d M Y'));
}
protected function formattedAttendedAt(): Attribute
{
return Attribute::get(fn () => $this->attended_at?->translatedFormat('l, d M Y H:i'));
}
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function classSession(): BelongsTo public function classSession(): BelongsTo
{ {
return $this->belongsTo(ClassSession::class); return $this->belongsTo(ClassSession::class);

View File

@ -10,8 +10,12 @@
class Changelog extends Model class Changelog extends Model
{ {
// --- Traits ---
use HasFactory, SoftDeletes; use HasFactory, SoftDeletes;
// --- Properties ---
protected $fillable = [ protected $fillable = [
'version', 'version',
'release_date', 'release_date',
@ -21,24 +25,33 @@ class Changelog extends Model
'description', 'description',
]; ];
/** // --- Casts ---
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [ protected $casts = [
'release_date' => 'date',
'changes' => 'array', 'changes' => 'array',
'release_date' => 'date',
'type' => ChangelogType::class, 'type' => ChangelogType::class,
]; ];
public function formattedVersion(): Attribute // --- Accessors & Mutators ---
protected function formattedVersion(): Attribute
{ {
return Attribute::get(fn () => strtoupper($this->version)); return Attribute::get(fn () => strtoupper($this->version));
} }
public function formattedReleaseDate(): Attribute protected function formattedReleaseDate(): Attribute
{ {
return Attribute::get(fn () => $this->release_date->translatedFormat('l, d M Y')); return Attribute::get(fn () => $this->release_date->translatedFormat('l, d M Y'));
} }
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
} }

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -10,20 +11,55 @@
class ClassSession extends Model class ClassSession extends Model
{ {
// --- Traits ---
use HasFactory, SoftDeletes; use HasFactory, SoftDeletes;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Casts ---
protected function casts(): array protected function casts(): array
{ {
return [ return [
'date' => 'date', 'date' => 'date',
'end_time' => 'datetime',
'session_number' => 'integer', 'session_number' => 'integer',
'start_time' => 'datetime', 'start_time' => 'datetime',
'end_time' => 'datetime',
]; ];
} }
// --- Accessors & Mutators ---
protected function formattedDate(): Attribute
{
return Attribute::get(fn () => $this->date?->translatedFormat('l, d M Y'));
}
protected function formattedStartTime(): Attribute
{
return Attribute::get(fn () => $this->start_time?->translatedFormat('H:i'));
}
protected function formattedEndTime(): Attribute
{
return Attribute::get(fn () => $this->end_time?->translatedFormat('H:i'));
}
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function assignments(): HasMany public function assignments(): HasMany
{ {
return $this->hasMany(Assignment::class); return $this->hasMany(Assignment::class);

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
@ -10,10 +11,28 @@
class Course extends Model class Course extends Model
{ {
// --- Traits ---
use HasFactory, SoftDeletes; use HasFactory, SoftDeletes;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Accessors & Mutators ---
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function assignments(): HasMany public function assignments(): HasMany
{ {
return $this->hasMany(Assignment::class); return $this->hasMany(Assignment::class);

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -10,10 +11,16 @@
class CourseSchedule extends Model class CourseSchedule extends Model
{ {
// --- Traits ---
use HasFactory, SoftDeletes; use HasFactory, SoftDeletes;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Casts ---
protected function casts(): array protected function casts(): array
{ {
return [ return [
@ -22,13 +29,37 @@ protected function casts(): array
]; ];
} }
public function course(): BelongsTo // --- Accessors & Mutators ---
protected function formattedStartTime(): Attribute
{ {
return $this->belongsTo(Course::class); return Attribute::get(fn () => $this->start_time?->translatedFormat('H:i'));
} }
protected function formattedEndTime(): Attribute
{
return Attribute::get(fn () => $this->end_time?->translatedFormat('H:i'));
}
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function attendances(): HasMany public function attendances(): HasMany
{ {
return $this->hasMany(Attendance::class); return $this->hasMany(Attendance::class);
} }
public function course(): BelongsTo
{
return $this->belongsTo(Course::class);
}
} }

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -11,17 +12,35 @@
class Material extends Model implements HasMedia class Material extends Model implements HasMedia
{ {
// --- Traits ---
use HasFactory, InteractsWithMedia, SoftDeletes; use HasFactory, InteractsWithMedia, SoftDeletes;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
public function course(): BelongsTo // --- Accessors & Mutators ---
protected function formattedCreatedAt(): Attribute
{ {
return $this->belongsTo(Course::class); return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
} }
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function classSession(): BelongsTo public function classSession(): BelongsTo
{ {
return $this->belongsTo(ClassSession::class); return $this->belongsTo(ClassSession::class);
} }
public function course(): BelongsTo
{
return $this->belongsTo(Course::class);
}
} }

View File

@ -5,6 +5,7 @@
use App\Enums\Sex; use App\Enums\Sex;
use Illuminate\Database\Eloquent\Attributes\Scope; use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -14,10 +15,16 @@
class Student extends Model class Student extends Model
{ {
// --- Traits ---
use HasFactory, SoftDeletes; use HasFactory, SoftDeletes;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Casts ---
protected function casts(): array protected function casts(): array
{ {
return [ return [
@ -26,6 +33,8 @@ protected function casts(): array
]; ];
} }
// --- Scopes ---
#[Scope] #[Scope]
protected function male(Builder $query): void protected function male(Builder $query): void
{ {
@ -38,6 +47,25 @@ protected function female(Builder $query): void
$query->where('sex', Sex::Female); $query->where('sex', Sex::Female);
} }
// --- Accessors & Mutators ---
protected function formattedDateOfBirth(): Attribute
{
return Attribute::get(fn () => $this->date_of_birth?->translatedFormat('l, d M Y'));
}
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function assignmentPins(): HasMany public function assignmentPins(): HasMany
{ {
return $this->hasMany(AssignmentPin::class); return $this->hasMany(AssignmentPin::class);

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -11,15 +12,28 @@
class StudyGroup extends Model class StudyGroup extends Model
{ {
// --- Traits ---
use HasFactory, SoftDeletes; use HasFactory, SoftDeletes;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
public function isLeader(Student $student): bool // --- Accessors & Mutators ---
protected function formattedCreatedAt(): Attribute
{ {
return $this->leader_id === $student->id; return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
} }
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function assignmentSubmissions(): HasMany public function assignmentSubmissions(): HasMany
{ {
return $this->hasMany(AssignmentSubmission::class); return $this->hasMany(AssignmentSubmission::class);
@ -60,6 +74,13 @@ public function students(): BelongsToMany
return $this->belongsToMany(Student::class, 'study_group_members'); return $this->belongsToMany(Student::class, 'study_group_members');
} }
// --- Methods ---
public function isLeader(Student $student): bool
{
return $this->leader_id === $student->id;
}
public static function getBusyStudentIdsForCourses(array $courseIds, ?int $excludeGroupId = null): array public static function getBusyStudentIdsForCourses(array $courseIds, ?int $excludeGroupId = null): array
{ {
$busyMemberIds = StudyGroupMember::whereHas( $busyMemberIds = StudyGroupMember::whereHas(

View File

@ -2,16 +2,35 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
class StudyGroupMember extends Model class StudyGroupMember extends Model
{ {
// --- Traits ---
use HasFactory; use HasFactory;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
// --- Accessors & Mutators ---
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function student(): BelongsTo public function student(): BelongsTo
{ {
return $this->belongsTo(Student::class); return $this->belongsTo(Student::class);

View File

@ -20,15 +20,21 @@
class User extends Authenticatable implements FilamentUser class User extends Authenticatable implements FilamentUser
{ {
// --- Traits ---
/** @use HasFactory<UserFactory> */ /** @use HasFactory<UserFactory> */
use HasFacehashAvatar, HasFactory, HasRoles, Notifiable, SoftDeletes; use HasFacehashAvatar, HasFactory, HasRoles, Notifiable, SoftDeletes;
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
protected $hidden = [ protected $hidden = [
'password', 'password',
]; ];
// --- Casts ---
protected function casts(): array protected function casts(): array
{ {
return [ return [
@ -37,6 +43,8 @@ protected function casts(): array
]; ];
} }
// --- Scopes ---
#[Scope] #[Scope]
protected function active(Builder $query): void protected function active(Builder $query): void
{ {
@ -49,10 +57,7 @@ protected function inactive(Builder $query): void
$query->where('is_active', IsActive::Inactive); $query->where('is_active', IsActive::Inactive);
} }
public function canAccessPanel(Panel $panel): bool // --- Accessors & Mutators ---
{
return $this->is_active === IsActive::Active;
}
protected function name(): Attribute protected function name(): Attribute
{ {
@ -61,20 +66,39 @@ protected function name(): Attribute
); );
} }
public function student(): HasOne protected function formattedCreatedAt(): Attribute
{ {
return $this->hasOne(Student::class); return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
} }
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function settings(): HasOne public function settings(): HasOne
{ {
return $this->hasOne(UserSetting::class)->withDefault([ return $this->hasOne(UserSetting::class)->withDefault([
'notif_style' => NotifStyle::Cheerful, 'notif_style' => NotifStyle::Cheerful,
'primary_color' => 'amber', // Cheerful yellow 'primary_color' => 'amber',
'font' => 'Inter', 'font' => 'Inter',
'content_width' => 'full', 'content_width' => 'full',
'border_radius' => 'lg', 'border_radius' => 'lg',
'top_navigation' => false, 'top_navigation' => false,
]); ]);
} }
public function student(): HasOne
{
return $this->hasOne(Student::class);
}
// --- Methods ---
public function canAccessPanel(Panel $panel): bool
{
return $this->is_active === IsActive::Active;
}
} }

View File

@ -3,17 +3,17 @@
namespace App\Models; namespace App\Models;
use App\Enums\NotifStyle; use App\Enums\NotifStyle;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
class UserSetting extends Model class UserSetting extends Model
{ {
// --- Properties ---
protected $guarded = ['id']; protected $guarded = ['id'];
public function user(): BelongsTo // --- Casts ---
{
return $this->belongsTo(User::class);
}
protected function casts(): array protected function casts(): array
{ {
@ -22,4 +22,23 @@ protected function casts(): array
'top_navigation' => 'boolean', 'top_navigation' => 'boolean',
]; ];
} }
// --- Accessors & Mutators ---
protected function formattedCreatedAt(): Attribute
{
return Attribute::get(fn () => $this->created_at->translatedFormat('l, d M Y H:i'));
}
protected function formattedUpdatedAt(): Attribute
{
return Attribute::get(fn () => $this->updated_at?->translatedFormat('l, d M Y H:i'));
}
// --- Relations ---
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
} }