Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

joshuadempseygb's avatar

Eloquent Accessor

I have an eloquent Accessor for my model (shift - representing a workers shift) that I would like to bypass.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Carbon\Carbon;

class Shift extends Model
{
	use HasFactory, HasUuids;

    public $guarded = [];

    protected function date(): Attribute
    {
        return Attribute::make(
            get: fn ($value) =>  Carbon::parse($value)->format('l, jS F '),
        );
    }
}

The accessor date returns a nicely formatted date string for me to show on the front end. However, to edit the resource I need the date in it's "raw" value, without being modified by the accessor.

I've tried a few methods such as calling

$model->getOriginal('name');

And also

$model->getAttributes()['name']

Whatever method I use they always return the accessor produced value. If I delete the accessor I get the raw unformatted date which is what I need.

Does anyone have any suggestions on where to look?

Thanks

0 likes
5 replies
LaryAI's avatar
Level 58

To bypass the accessor and retrieve the raw value of the date attribute, you can use the getAttributeValue method provided by Eloquent. Here's an example of how you can modify your code to achieve this:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Carbon\Carbon;

class Shift extends Model
{
    use HasFactory, HasUuids;

    public $guarded = [];

    protected function date(): Attribute
    {
        return Attribute::make(
            get: fn ($value) =>  Carbon::parse($value)->format('l, jS F '),
        );
    }

    public function getRawDateAttribute()
    {
        return $this->getAttributeValue('date');
    }
}

In this solution, we added a new method called getRawDateAttribute to the Shift model. This method uses the getAttributeValue method to retrieve the raw value of the date attribute, bypassing the accessor.

Now, you can access the raw date value by calling $model->raw_date on an instance of the Shift model.

joshuadempseygb's avatar

@DhPandya Thank you this does indeed return the raw date. However, when passing to my Vue front end, for some reason I can't get the value to appear properly.

Let me explain.

Here's my controller for returning the Edit view.

 /**
     * Show the form for editing the specified resource.
     */
    public function edit(Shift $shift)
    {
		// This line isn't relevant but leaving it just incase.
        $workplace = Workplace::findOrFail($shift['workplace_id'])->with('employees', 'jobRoles')->first();

       $shift->date = $shift->getRawOriginal('date');
        return Inertia::render('Shifts/Edit', ['shift' => $shift, 'workplace' => $workplace]);
    }

If I pass this to the Vue frontend, for some strange reason the date property is still "Tuesday 10th October."

However If I use the below code:

 $shift->unf_date = $shift->getRawOriginal('date');

And access unf_date on the frontend the value correctly appears as a string (which is what I need for populating a HTML5 Date Input). The issue is now resolved, thank you for your help, but is there any clarification as to why overwriting the date property on $shift is not working?

Regards

DhPandya's avatar

@joshuadempseygb You can not update the model property until you are not calling the save() of the model. To use your custom property that is not included with the model you can use $appends of the Model.

If you find your answer then you can mark the question as solved.

Thanks.

1 like
joshuadempseygb's avatar

@DhPandya Ah gotcha, that makes total sense. Thanks for your help and the follow up, I'll read into $appends now, thank you :)

Please or to participate in this conversation.