a-dev-coder-f's avatar

Setting another Attribute in a mutator Laravel 11

When I set the book location value, I want to set the latitude and longitude values to 0 as well.

// Book Model

class Book extends Model {
	protected $fillable = [
		'latitude',
		'longitude',
		'location'
	]

    protected function location(): Attribute
    {
        return Attribute::make(
            set: function ($value, $attributes) {
                $this->latitude = 0;
                $this->longitude = 0;

                return $value;
            }
        );
    }
}

When I try to set the lat/long inside the attribute set, although I can see those attribute values changing. It will not save the results when I'm back out of the location function.

// $book->latitude = 1;
// $book->longitude = 1;

// When i'm inside the location attribute set function, the lat/long are set to 0 properly
$book->location = 'Test';

// Now I'm back outside, the lat/long haven't changed based on what I set before
// $book->latitude is still 1
// $book->longitude is still 1 
$book->save();

I suppose you could update the model via ->update and that'd work. Or use model events to set these values if the location is different from the original.

Is this possible to do? I've tried variations like $this->setAttribute('latittude', 0) but they all aren't saved after stepping out of the attribute set function.

0 likes
4 replies
a-dev-coder-f's avatar

However, the old setAttributes format works

    public function setLocationAttribute($value): void
    {
        if ($this->attributes['location'] !== $value) {
            $this->attributes['latitude'] = 0;
            $this->attributes['longitude'] = 0;
        }

        $this->attributes['location'] = $value;
    }
Glukinho's avatar
Level 31

https://laravel.com/docs/12.x/eloquent-mutators#mutating-multiple-attributes

Sometimes your mutator may need to set multiple attributes on the underlying model. To do so, you may return an array from the set closure. Each key in the array should correspond with an underlying attribute / database column associated with the model:

I also recommend to set longitude/latitude to null, not integer 0. The meaning of null is "value unknown" or "value is not present" (which you want in your case, I suppose), while longitude and latitude both can have value 0 (this is a specific point on Earth).

1 like

Please or to participate in this conversation.