Повторное использование аксессоров и мутаторов

В нескольких моих моделях у меня есть такой код

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

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

Иногда поле, которое я изменяю, называется покупка или цена, но код тот же (изменение 7,99 на 799 для сохранения в БД и обратное изменение по возвращении).

Если бы все поля были названы одинаково, я мог бы использовать черту, однако они немного отличаются .... есть ли способ настроить что-то похожее на поля даты, которые автоматически мутируют экземпляры углерода?


person Wizzard    schedule 09.06.2016    source источник
comment
Вы можете использовать traits (PHP ›= 5.5). Или, может быть, abstract занятий.   -  person Daniel W.    schedule 09.06.2016
comment
@DanFromGermany Я упомянул, что не могу использовать черты, так как имя поля отличается для разных моделей ... если я что-то не упустил ...   -  person Wizzard    schedule 10.06.2016


Ответы (2)


Одно из решений состоит в том, чтобы определить поля, которые имеют дело с преобразованием долларов в центы, в моделях, которые имеют такие поля, а затем использовать трейт для переопределения глобальных мутаторов/аксессоров.

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;
             }
        }
    }
}
person tanerkay    schedule 09.06.2016
comment
Это выглядит очень многообещающе! Обратите внимание, я использую $value * 0,01 вместо деления, поэтому мне не нужно проверять 0 (деление на ноль) и обрабатывать это. Спасибо! - person Wizzard; 10.06.2016
comment
Одним из недостатков является то, что магические вызовы дороги, PHP не может оптимизировать код и будет медленнее, чем правильные определения методов. - person Daniel W.; 10.06.2016
comment
Другим недостатком является то, что вы можете сделать это только один раз. Выполнение этого для денег, а затем также выполнение этого для чего-то еще не удастся, потому что нельзя использовать одно и то же имя функции в двух разных трейтах, используемых одновременно. - person Wizzard; 19.06.2016

Вас может заинтересовать 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',
    ];
}

Пакет позволяет создавать собственные расширения доступа/мутаторов.

person topclaudy    schedule 14.12.2018