在模型上添加方法

时间:2018-02-16 21:11:23

标签: php laravel oop

我正在使用Laravel

Transaction.php模型

In [10]: {i.replace('[:AMide]', '').replace('[:dkja]', '') for i in set1}
Out[10]: {'*klj?', 'DKJ?', 'JKLJS?', 'TRered?', 'abkjld:Sure:STe?', 'bl:VOLTe?'}

我想添加一些像getClassColore()这样的方法,但我这样做

In [11]: import re

In [12]: {re.sub(r'\[[^]]+\]', r'', i) for i in set1}
Out[12]: {'*klj?', 'DKJ?', 'JKLJS?', 'TRered?', 'abkjld:Sure:STe?', 'bl:VOLTe?'}

我的问题是:我有什么方法可以做到以下

//get user transactions
public static function getTransactions($user_id)
{
    return Transaction::where('user_id', $user_id)->latest()->get();
}

更多OOP方式

提前致谢

3 个答案:

答案 0 :(得分:1)

你应该研究model accessors and mutators。如果您的模型包含type字段用于购买,取款,收费等,那么您可以执行以下操作:

// Transaction.php
protected $classes = [
    'buy' => 'text-danger',
    'withdraw' => 'text-danger',
    'charge' => 'text-success',
    'profit' => 'text-success',
    'return' => 'text-success'
];

public function getClassColorAttribute()
{
    // type would be a column containing buy or withdraw or charge, etc.
    return $this->classes[$this->type] ?? 'text-muted';
}

您可以像

那样访问它
$transaction->class_color

答案 1 :(得分:1)

你可以简单地将你的功能放在Transaction模型上,如下所示:

public function getColor()
{
    switch ($this->deciding_attribute) {
        case 'buy':
        case 'withdraw':
            return 'text-danger';

        case 'charge':
        case 'profit':
        case 'return':
            return 'text-success';

        default:
            return 'text-muted';
}

或者您使用地图作为颜色:

protected $colors = [
    'buy'      => 'text-danger',
    'withdraw' => 'text-danger',
    'charge'   => 'text-success',
    'profit'   => 'text-success',
    'return'   => 'text-success',
];

public function getColor()
{
    $this->colors[$this->deciding_attribute] ?? 'text-muted';
}

然后你可以查询你的交易并调用它们的功能:

$transactions = Transaction::where('user_id', $user_id)->latest()->take(5)->get();

foreach ($transactions as $transaction) {
    echo $transaction->getColor();
}

作为旁注,在视图/组件区域中将此逻辑放在某处是有意义的。在我看来,它不属于该模型。

顺便说一下,我从break;删除了switch-case语句,因为在这种情况下它们没用。如果在return之前有break声明,则无论如何都永远无法联系break

您也可以直接从User模型获取交易,以遵循更多OOP方法:

class User
{
    // your other model code

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function transactions()
    {
        return $this->hasMany('App\Transactions', 'user_id', 'id');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function latestTransaction()
    {
        return $this->hasOne('App\Transactions', 'user_id', 'id')
            ->latest();
    }
}

答案 2 :(得分:1)

我认为最终的OOP方式是使用类似Decorator Pattern的演示者。请阅读博文"Presenters in Laravel"。所以,基本上你可以为你的模型创建一个演示者:

abstract class Presenter
{
    protected $model;

    public function __construct(Model $model)
    {
        $this->model = $model;
    }

    public function __call($method, $args)
    {
        return call_user_func_array([$this->model, $method], $args);
    }

    public function __get($name)
    {
        return $this->model->{$name};
    }
}

class HtmlPresenter extends Presenter
{
    public function getColor()
    {
        switch ($this->operation) {
            case 'buy':
            case 'withdraw':
                return 'text-danger';
            case 'charge':
            case 'profit':
            case 'return':
                return 'text-success';
            default:
                return 'text-muted';
        }
    }
}

然后,声明你有一个模型集合,你可以像下面那样装饰它们(使用mapInto集合方法):

$transactions = Transaction::getTransactions(5)
    ->mapInto(HtmlPresenter::class);

foreach($transactions as $transaction) {
    echo $transaction->getColor();
}

上述博文的作者甚至创建了Laravel package,简化了装饰。