【问题标题】:Laravel Eloquent setAppends() to entire model collection?Laravel Eloquent setAppends() 到整个模型集合?
【发布时间】:2018-04-20 21:54:23
【问题描述】:

根据https://laravel.com/docs/5.6/eloquent-serialization,可以在模型实例上使用setAppends 将任何可用的额外属性动态添加到模型中。但是,除了遍历集合之外,我还没有找到对模型集合执行此操作的方法。

有没有更聪明的方法来做到这一点?像这样:

$facilities = Facility:all();
$facilities->setAppends();

目前唯一的选择是:

foreach ($facilities as $facility) {
    $facility->setAppends([
        'your_attribute_here'
    ]);
}

编辑:澄清一下,我想在运行时动态地执行此操作。我定义的额外属性在获取模型的任何地方都不需要,并且可能会导致大量额外开销。

【问题讨论】:

  • 添加accessor和appends属性就不需要做任何额外的工作了。
  • @chanafdo 请在底部查看我的编辑。我想动态地做到这一点。
  • 查看答案。

标签: php laravel eloquent


【解决方案1】:

你可以使用higher order messages:

$facilities->each->setAppends([
    'your_attribute_here'
]);

【讨论】:

  • 不确定它是否像这样工作。 each 收到一个 Closure,但即使 $model->each(function ($row) { $row->setAppends([...]); }) 也不起作用
  • 我的错误,我试图将each 应用于查询而不是集合。现在它可以工作了。
【解决方案2】:

在您的模型中添加以下访问器

public function getCustomAttribute()
{
    return 'some-value';
}

Collection 上定义一个setAppends 宏,最好在服务提供者(例如AppServiceProvider)中,以便您可以在任何地方使用它:

Collection::macro('setAppends', function ($attributes) {
    return $this->map(function ($item) use ($attributes) {
        return $item->setAppends($attributes);
    });
});

那你就可以了

$facilities = Facility:all();
$facilities->setAppends([
    'some-value'
]);

【讨论】:

  • 这很好用,谢谢。基于此,我提出了一个更通用的版本,可以以与原始功能相同的方式使用。但是,为了确定,我想了解一些事情。这个宏不只是像我的例子那样循环遍历整个集合吗?另外,我应该在您的答案中使用编辑功能来发布通用版本还是..?我不太确定这部分的礼仪。
  • 是的,下面只是循环和动态追加
  • 很公平。我还发现了有关 Collection 宏的更多信息,并发现将它们放在服务提供者中会很好。
  • 是的。你可以把它放在AppServiceProvider
  • 问题是执行了多个查询;集合中的每一行一个。有没有办法在单个查询中填充它?
【解决方案3】:

在您的模型中定义 $appends 属性并添加您的自定义属性,例如

protected $appends = ['your_attribute_here'];

要为这些自定义属性设置值,请定义accessor 方法

public function getYourAttributeHereAttribute()
{
    return "some value or model attribute";
}

【讨论】:

  • 请在底部查看我的编辑。我想动态地做到这一点。
猜你喜欢
  • 1970-01-01
  • 2019-09-08
  • 2016-09-05
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 2018-07-19
  • 2017-04-12
  • 1970-01-01
相关资源
最近更新 更多