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()
函数会很有用,但它只能获取单个参数。但是我想用 两个参数,id
和 name
获得输出,如下所示:
[
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\Collection
和Illuminate\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 模型集合的多个属性的主要内容,如果未能解决你的问题,请参考以下文章