Wizzard
Wizzard

Reputation: 12702

Reusing an accessors & mutators

In several of my models I have code like this

public function setTotalAttribute($value)
{
    return $this->attributes['total'] = $value * 100;
}

public function getTotalAttribute($value)
{
    return $value * 0.01;
}

Sometimes the field that I am mutating is called purchase or price, but the code is the same (changing 7.99 to 799 to store in the DB, and change it back on return).

If all the fields were named the same I could use a trait, however they are slightly different.... is there a way I can setup something similar to the date fields which auto-mutate to Carbon instances?

Upvotes: 1

Views: 2085

Answers (2)

topclaudy
topclaudy

Reputation: 819

You might be interested in https://github.com/topclaudy/eloquent-mutators

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use \Awobaz\Mutator\Mutable;

    protected $accessors = [
        'title'   => 'trim_whitespace',
        'content' => 'trim_whitespace',
    ];
}

The package allows you to create custom accessors/mutators extensions.

Upvotes: 1

tanerkay
tanerkay

Reputation: 3930

One solution is to define the fields that deal with dollars/cents conversion in the models that have such fields, and then use a trait to override the global mutators/accessors.

class Model
{
    use HasMoneyFields;

    protected $moneyFields = ['purchase', 'price', 'total'];
}

trait HasMoneyFields
{        
    public function getAttributeValue($key)
    {
        $value = parent::getAttributeValue($key);

        if (property_exists($this, 'moneyFields')) {
             if (in_array($key, $this->moneyFields)) {
                 $value /= 100;
             }
        }

        return $value;
    }

    public function setAttribute($key, $value)
    {
        parent::setAttribute($key, $value);

        if (property_exists($this, 'moneyFields')) {
             if (in_array($key, $this->moneyFields)) {
                 $this->attributes[$key] = $value * 100;
             }
        }
    }
}

Upvotes: 3

Related Questions