Laravel 5 - 有条件附加变量

问题描述 投票:0回答:2

先说几句

我知道您可以使用

protected $appends = ["your", "vars", "here"];
数组将变量附加到模型数组和 json 表示形式。但想象一下以下情况:

情况

我们的用例是一个虚构的游戏或类似游戏:

想象一下,我们有一个

User
模型,其中包含(人类)用户的简单信息,例如全名、地址等。

现在,我们还有一个

Faction
模型,代表该用户的派系/出身/公会/...。

Faction
模型在检索用户时是急切加载的,因为几乎每次显示用户信息时都需要Faction名称。

A

User
还有
DailyStatistics
,其中包含有关他们每日分数的一些信息(简单的分数就足够了)。

线索

因为我想知道a派系的积分,也就是用户积分的总和,所以我想到了追加一个新变量

totalPoints

getTotalPointsAttribute
函数看起来像这样:

function getTotalPointsAttribute(){
    return $this->users->sum->getTotalPoints();
}

问题

现在每次我们检索用户时,急切加载的派系也会想要计算

totalPoints
属性。这意味着我们每个用户都有大量的开销

问题

有没有办法避免这样的情况发生?我可以“有条件地”附加变量吗?属性隐藏时是否计算?

我尝试将

totalPoints
变量包装在一个简单的函数中,而不是访问器中。问题是,像 VueJS 这样的前端框架需要访问
totalPoints
变量(或访问端点来检索该值,但此解决方案是最不受欢迎的)。

php laravel vuejs2 laravel-5.4
2个回答
15
投票

我遇到了这个问题,因为我想动态追加,但不希望它自动追加到任何其他控制器/模型上(另一种方法是为同一个表生成 2 个模型,这很难维护)。

目前我正在维护 Laravel 5.4(因为他们拒绝将 PHP5.6 升级到 PHP7)

适用于 Laravel 5.4 及以下版本

只需在完成查询构建器 get() 后添加一个闭包

->each(function ($items) {
    $items->append('TotalPoints');
);

原始解决方案来源:laravel-how-to-ignore-an-accessor

$openOrders = Order::open()->has('contents')
->get(['id','date','tableName'])
->each(function ($items) {
    $items->append('TotalPoints');
);

您的模型仍然包含

public function getTotalPointsAttribute()
{
    return $this->users->sum->getTotalPoints();
}

现在您可以删除/注释掉模型中的附加内容:

protected $appends = [
    'TotalPoints',
];

或者,如果您使用的是 Laravel 5.5 及更高版本,您可以像这样使用集合魔法:

$openOrders->each->setAppends(['TotalPoints']);

Laravel 5.5 及更高版本现在有 Laravel 5.6 #Appending At Run Time


0
投票

您可以使用 Laravel 在运行时追加

首先为值定义一个访问器

function getTotalPointsAttribute(){
  return $this->users->sum->getTotalPoints();
}

然后,如果您想检索多个模型,请像这样使用它:

$users->each->append(['total_points']);

// Or if you want to override the entire array
// of appended properties for a given models
$users->each->setAppends(['total_points']);

或者如果您只想检索单个模型,只需执行以下操作:

$user->total_points;

// append(['total_points']) and setAppends(['total_points']) is also usable;
© www.soinside.com 2019 - 2024. All rights reserved.