是否有更短的方法来执行以下操作(
@user.employees.map { |e| { id: e.id, name: e.name } }
# => [{ id: 1, name: 'Pete' }, { id: 2, name: 'Fred' }]
User
has_many
名员工。这两个类都继承自ActiveRecord::Base
。
我不喜欢上面提到的两件事
有更好的方法吗?
答案 0 :(得分:43)
<强>更新强>
请参阅@jamesharker的解决方案:来自ActiveRecord&gt; = 4,pluck
接受多个参数:
@user.employees.pluck(:id, :name)
以前的答案:
对于rails&gt; = 3.2中的单个列,您可以执行以下操作:
@user.employees.pluck(:name)
...但是你需要选择两个属性,你可以这样做:
@user.employees.select([:id, :name]).map {|e| {id: e.id, name: e.name} }
# or map &:attributes, maybe
如果确实需要更低级别的操作,请查看使用select_all
答案 1 :(得分:36)
在ActiveRecord&gt; = 4 pluck接受多个参数,因此此示例将变为:
@user.employees.pluck(:id, :name)
答案 2 :(得分:7)
如果您遇到Rails 3,可以添加this .pluck_all
分机:http://meltingice.net/2013/06/11/pluck-multiple-columns-rails/
答案 3 :(得分:0)
添加这个猴子补丁,它在Rails 3中提供多列拔除功能。
# config/initializers/pluck_all.rb
if Rails.version[0] == '3'
ActiveRecord::Relation.class_eval do
def pluck(*args)
args.map! do |column_name|
if column_name.is_a?(Symbol) && column_names.include?(column_name.to_s)
"#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}"
else
column_name.to_s
end
end
relation = clone
relation.select_values = args
klass.connection.select_all(relation.arel).map! do |attributes|
initialized_attributes = klass.initialize_attributes(attributes)
attributes.map do |key, attr|
klass.type_cast_attribute(key, initialized_attributes)
end
end
end
end
end
如果您不想覆盖原始的pluck
功能,请将方法从pluck_all
重命名为pluck
答案 4 :(得分:0)
在制作rails 3方法方面,其行为与Rails 4采用多列相同。这会输出一个类似的数组(而不是散列键值集合)。如果你来升级并想要清理代码,这应该可以节省一些痛苦。
module ActiveRecord
class Relation
def pluck_all(*args)
args.map! do |column_name|
if column_name.is_a?(Symbol) && column_names.include?(column_name.to_s)
"#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}"
else
column_name.to_s
end
end
relation = clone
relation.select_values = args
klass.connection.select_all(relation.arel).map! do |attributes|
initialized_attributes = klass.initialize_attributes(attributes)
attributes.map do |key, attribute|
klass.type_cast_attribute(key, initialized_attributes)
end
end
end
end
end
站在巨人和所有人的肩膀上
答案 5 :(得分:0)
在我从Rails 3.2升级到Rails 4之前,pluck_all
方法运行良好。
这是一个gem pluck_all来解决这个问题,不仅在Rails 3中而且在Rails 4和Rails 5中支持pluck_all
方法。希望这将有助于那些将要升级rails版本的人。
答案 6 :(得分:0)
另一种选择是:
@user.employees.select(:id, :name).as_json
#=> [{"id" => 1, "name" => "Pete"}, {"id" => 2, "name" => "Fred"}]
我可以想象你宁愿使用符号键。
如果是这种情况,请使用#symbolize_keys
方法。
@user.employees.select(:id, :name).as_json.map(&:symbolize_keys)
#=> [{id: 1, name: "Pete"}, {id: 2, name: "Fred"}]
请参阅:http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html#method-i-as_json