我该怎么转:
Person.all.pluck(:id, :name)
到
[{id: 1, name: 'joe'}, {id: 2, name: 'martin'}]
不必.map每个值(因为当我从.pluck中添加或删除时,我必须对.map执行相同的操作)
答案 0 :(得分:24)
您可以map
结果:
Person.all.pluck(:id, :name).map { |id, name| {id: id, name: name}}
如@alebian所述: 这比
更有效Person.all.as_json(only: [:id, :name])
原因:
pluck
仅返回已使用的列(:id,:name),而另一个解决方案返回所有列。根据表格的宽度(列数),这会产生很大差异Person
个对象,也不需要为模型分配属性等等。相反,它只返回一个包含一个整数和一个字符串的数组。as_json
再次比简单map
有更多开销,因为它是将模型转换为哈希的通用实现答案 1 :(得分:23)
你可以这么做
Person.select(:id,:name).as_json
你也可以试试这个
Person.all.as_json(only: [:id, :name])
答案 2 :(得分:10)
我看到三个选项:
1) pluck
加map
:
Person.pluck(:id, :name).map { |p| { id: p[0], name: p[1] } }
2) pluck
加上map
加上zip
以及一个使其成为DRY-er的变量:
attrs = %w(id name)
Person.pluck(*attrs).map { |p| attrs.zip(p).to_h }
3)或者您可能根本不使用pluck
,尽管效果要差得多:
Person.all.map { |p| p.slice(:id, :name) }
答案 3 :(得分:5)
如果使用postgresql,则可以在pluck方法中使用json_build_object
函数:
https://www.postgresql.org/docs/9.5/functions-json.html
这样,您可以让db创建哈希。
Person.pluck("json_build_object('id', id, 'name', name)")
#=> [{id: 1, name: 'joe'}, {id: 2, name: 'martin'}]
答案 4 :(得分:3)
在使用ID作为键并且名称为值:
之后,可以使用哈希值Person.all.pluck(:id, :name).to_h
{ 1 => 'joe', 2 => 'martin' }
不确定这是否符合您的需求,但作为选项提供。
答案 5 :(得分:3)
您可以使用名称恰当的pluck_to_hash gem: https://github.com/girishso/pluck_to_hash
它将使用pluck_to_hash方法扩展AR,其方法如下:
Post.limit(2).pluck_to_hash(:id, :title)
#
# [{:id=>213, :title=>"foo"}, {:id=>214, :title=>"bar"}]
#
Post.limit(2).pluck_to_hash(:id)
#
# [{:id=>213}, {:id=>214}]
它声称比使用AR select
和as_json
答案 6 :(得分:2)
答案 7 :(得分:1)
最简单的方法是结合使用pluck
方法和zip
方法。
attrs_array = %w(id name)
Person.all.pluck(attrs_array).map { |ele| attrs_array.zip(ele).to_h }
如果在整个应用程序中都使用该方法,则也可以创建一个辅助方法。
def pluck_to_hash(object, *attrs)
object.pluck(*attrs).map { |ele| attrs.zip(ele).to_h }
end
考虑通过将self
声明为默认接收者,而不是将Person.all
作为object
变量来进行修改。
详细了解zip。
答案 8 :(得分:0)
如果您有多个属性,可以这样做是为了保持整洁:
Item.pluck(:id, :name, :description, :cost, :images).map do |item|
{
id: item[0],
name: item[1],
description: item[2],
cost: item[3],
images: item[4]
}
end
答案 9 :(得分:0)
这是一种对我有效的方法:
def pluck_to_hash(enumerable, *field_names)
enumerable.pluck(*field_names).map do |field_values|
field_names.zip(field_values).each_with_object({}) do |(key, value), result_hash|
result_hash[key] = value
end
end
end