Laravel 5.2 pluck() 来自 Eloquent 模型集合的多个属性

Posted

技术标签:

【中文标题】Laravel 5.2 pluck() 来自 Eloquent 模型集合的多个属性【英文标题】:Laravel 5.2 pluck() multiple attributes from Eloquent Model Collection 【发布时间】:2016-09-05 14:35:39 【问题描述】:

Laravel 5.2 有相当不错的 Helpers,我想用它们来做以下事情:

我有 Eloquent 模型合集:

$lesson->users(); // returns Eloquent collection of 3 users

pluck() 函数会很有用,但它只能获取单个参数。但是我想用 两个参数idname 获得输出,如下所示:

[
1=>['id'=>10,'name'=>'Michael Dook'],
2=>['id'=>16,'name'=>'Henry Babcock'],
3=>['id'=>19,'name'=>'Joe Nedd']
]

有什么优雅的解决方案吗?

【问题讨论】:

【参考方案1】:

如果你有一个模型集合,你可以使用:

$users->map->only('name', 'hobby');

// returns e.g.
// collect([
//     new User(['name' => 'matt', 'hobby' => 'coding']),
//     new User(['name' => 'tomo', 'hobby' => 'cooking']),
// ]);

这仅适用于模型,因为 only 方法仅适用于模型,不适用于您可能在集合中拥有的其他项目。

对于适用于混合对象类型、数组等的集合的通用、更强大的解决方案,您可以使用我为 Spatie 的 laravel-collection-macros package 贡献的 pluckMany 宏:

$collection->pluckMany(['name', 'hobby']);

// returns e.g.
// collect([
//     (object) ['name' => 'marco', 'hobby' => 'drinking'],
//     (object) ['name' => 'belle', 'hobby' => 'cross-stitch'],
// ]);

有关 pluckMany 的更多详细信息,请参阅我在 How to pluck multiple items from a Laravel Collection 上的博客文章

【讨论】:

【参考方案2】:

Laravel:5.7

如果方法返回关系

使用get()

例如

$lesson = Lesson::find(1);
$lesson->users()->get(['id', 'name']);

关于收藏

使用only()

$user = collect(['id' => 1, 'name' => 'Foo', 'role' => 'A']);
$user->only(['id', 'name']);

多个数组

$users = collect([
    ['id' => 1, 'name' => 'Foo', 'role' => 'A'],
    ['id' => 2, 'name' => 'Bar', 'role' => 'B'];
]);

$result = $users->map(function($user)
   return Arr::only($user, ['id', 'name']);
);

var_dump($result);

【讨论】:

这是错误的。 OP 说users() 方法返回一个collection。此解决方案仅在 users() 返回关系(查询生成器)时才有效。 这仍然行不通。 Collection::only 方法通过键选择集合的所有成员。对于 Eloquent Collections,这是模型的主键,对于您编写的基本 Collections,这是数组索引。要修复第二个示例,您可以更改地图以返回 Arr::only($user, ['id', 'name']) 您现在可以使用高阶消息在一行中完成此操作$users->map->only(['id', 'name']) laravel.com/docs/8.x/collections#higher-order-messages【参考方案3】:

如问题中所述,$lesson->users() 返回“3 个用户的 Eloquent 集合”。这与 users() 是 Lesson 模型上的关系不同,许多答案都错误地假设了这种关系,在这种情况下它将返回一个查询构建器。

假设集合中的用户是 Eloquent 模型,从 Laravel 5.5 开始你可以简单地这样做:

$lesson->users()->map->only('id', 'name');

如果用户是普通数组,你可以改用:

$lesson->users()->map(fn ($user) => Arr::only($user, ['id', 'name']));

【讨论】:

ahh,最后的实际答案在页面末尾显示。 span> 【参考方案4】:

在 Laravel 6 中。^

集合方法->only() 只返回集合中给定的ID。

->get() 方法中,您可以指定要返回的列。 在集合上,您可以使用方法->keyBy('id') 来设置数组的键。

要返回以 id 为 key 的记录以及包含 id 和 name 的数组,请使用以下代码:

$lesson->users()->get(['id', 'name'])->keyBy('id')->toArray()

【讨论】:

这是错误的。 OP 说 users() 方法返回一个集合。此解决方案仅在 users() 返回关系(查询生成器)时才有效。集合get() 方法只是通过其键返回集合成员。【参考方案5】:
$result = $lesson->users()->map(function($item) 
  return array('id' => $item->id, 'name' => $item->name)
);

应该做的伎俩。

【讨论】:

感谢您实际回答了所提出的问题,与大多数回复不同。【参考方案6】:

pluck() 辅助函数确实需要第二个参数。然后它将返回一个关联数组,其中第二个参数定义键。所以你会得到key => value 对的结果。

您知道您的条目将由 id 和 name 组成,也许这会有所帮助:

$lesson->users->pluck('name', 'id')->toArray();

这将返回:

[
   10 => 'Michael Dook',
   16 => 'Henry Babcock',
   19 => 'Joe Nedd'
]

我不确定 Laravel 5.2,但这适用于 Laravel 5.5

【讨论】:

【参考方案7】:

如果有人想“提取”多个属性并键入它们(示例结果由“名称”字段键入,“值”是项目本身 - 更改它以获取您感兴趣的属性数组):

$settings = \App\Setting::all()->map(function ($setting) 
    return ['key' => $setting->name, 'value' => $setting];
)->pluck('value', 'key')->toArray();

【讨论】:

【参考方案8】:

我知道这不是最近的问题,但如果有人稍后从谷歌偶然发现它,请参阅Only Collection Method

$lesson->users()->only("id", "name")->toArray(); 应该是你所追求的。

【讨论】:

在 Laravel 5.2 中,这会在调用 users() 时导致 Call to undefined method Illuminate\Database\Query\Builder::only() 错误,或者为 users 提供空集合(不带大括号) 您是否已经建立了关系?这在 5.2 中运行良好,因为我已经在该版本中对其进行了测试。 你确定你在5.2测试过吗?仔细观察后,这在5.2.45...Arr::only 方法中是行不通的,Illuminate\Support\CollectionIlluminate\Database\Eloquent\Collection 在内部使用只检查***键。假设示例中的users() 只是一个普通方法而不是关系,因为那时我完全不知道发生了什么:) 这是与用户的关系,它们作为集合返回,因此可以访问上述唯一的方法。 不是问题的解决方案。首先,对方法users() 的调用确实 返回任何类型的集合,而是返回一个QueryBuilder 对象,您必须改用魔术属性->user。这也是导致@Paul 问题的原因。其次,only() 收集方法与pluck() 的作用相同。 only() 返回存储在给定键之一下的基础集合的所有元素。另一方面,pluck() 试图找到每个集合项的给定键 inside 并返回它。【参考方案9】:

试试这个:

$lesson->users()->select('id', 'name')->get()->toArray();

【讨论】:

这仅对 Laravel 4 有效。在 Laravel 5 中,您会遇到完整性约束违规:字段列表中的列不明确 laravel。 这对数据库进行了新查询,因此不是理想的解决方案,因为他说他已经有一个集合(可能已经在实际代码中更改/过滤了)。 此外,您还会遇到包含附加值的问题,然后尝试将它们转换为数组的一部分,当它们为空时会失败。 @Fusion 这不是真的,这个解决方案适用于所有 Laravel 版本。您提到的错误消息是 SQL 错误,可能是由于您加入另一个表并尝试选择两个表中都存在的列。 问题描述中提到,$lesson->users() 返回 Eloquent 集合,所以它不起作用。

以上是关于Laravel 5.2 pluck() 来自 Eloquent 模型集合的多个属性的主要内容,如果未能解决你的问题,请参考以下文章

采摘渴望加载Laravel 5.2

关于 Laravel 5.7 中 Pluck 结果的问题

laravel的pluck用法

处理来自 PHPUnit (Laravel 5.2) 的自定义异常

将模型相互关联 Laravel

在 Laravel 5.2 中修改原生认证