SigalZ's avatar

Mutate with conditions

Hello,

I have a tinyInt column in a table that will hold 0 or 1.

When I display it in a view I want it to be displayed as 'Yes' for 1 or 'No' for 0 When I use it in the code I want to check if its True or False.

Is there a way to set it up in the Model?

I'm not sure how to do this function with a condition:

protected function emailReminder(): Attribute
    {
        return Attribute::make(
            get: fn ($value) => $value == 1 ? 'Yes' : 'No',
        );
    }

And how to return Yes or True in different cases?

0 likes
7 replies
LaryAI's avatar
Level 58

Yes, you can set up a mutator in your model to handle this. Here's an example:

class YourModel extends Model
{
    // ...

    public function getYourColumnAttribute($value)
    {
        return $value ? 'Yes' : 'No';
    }

    public function setYourColumnAttribute($value)
    {
        $this->attributes['your_column'] = $value ? 1 : 0;
    }
}

This mutator will automatically convert the value of your column to 'Yes' or 'No' when you retrieve it from the model, and it will convert 'Yes' or 'No' back to 1 or 0 when you set the value on the model. You can then use the column in your code as a boolean value (i.e. if ($model->your_column) { ... }).

tykus's avatar
tykus
Best Answer
Level 104

You cannot because the accessor method does not accept arguments.

You can make a separate accessor for presentation, and a cast for the boolean representation.

protected $casts = [
    'email_reminder' => 'boolean',
];

protected function emailReminderInWords(): Attribute
{
    return Attribute::make(
        get: fn ($value) => $value == 1 ? 'Yes' : 'No',
    );
}
1 like
SigalZ's avatar

@tykus Thank you, I still have a problem because I can't use a function when reading from the database, I need to get the value from the database as Yes or No without calling a function. Can't explain why here, too complicated. But thank you

tykus's avatar

@SigalZ you can add a raw expression to select the email_reminder (or a new alias), e.g. using MySQL

YourModel::query()
    ->selectRaw('*, CASE email_reminder WHEN 1 THEN "Yes" ELSE "No" END AS email_reminder')
    ->find($id);
1 like
Snapey's avatar

Create an accessor that returns textual version as a differently named attribute.

eg, if your column was called 'account_suspended', you could create accessor called accountSuspendedText which returns yes/no and then use that in your view, but the existing column name accountSuspended in your back-end code

1 like
tykus's avatar

@SigalZ that is a mutator; it defines how the value is persisted in the database.

Please or to participate in this conversation.