[英]Shortcut for plucking two attributes from an ActiveRecord object?
有没有更短的方法来执行以下操作(
@user.employees.map { |e| { id: e.id, name: e.name } }
# => [{ id: 1, name: 'Pete' }, { id: 2, name: 'Fred' }]
User
has_many
员工。 这两个类都继承自ActiveRecord::Base
。
我不喜欢以上两件事
有没有更好的办法?
更新:
见@ jamesharker的解决方案:从ActiveRecord的> = 4, pluck
接受多个参数:
@user.employees.pluck(:id, :name)
上一个答案:
对于rails> = 3.2中的单个列,可以执行以下操作:
@user.employees.pluck(:name)
...但是您必须选择两个属性,因此可以执行以下操作:
@user.employees.select([:id, :name]).map {|e| {id: e.id, name: e.name} }
# or map &:attributes, maybe
在ActiveRecord> = 4中, pluck接受多个参数,因此该示例将变为:
@user.employees.pluck(:id, :name)
如果你被卡住了Rails 3,您可以添加这个 .pluck_all
扩展: http://meltingice.net/2013/06/11/pluck-multiple-columns-rails/
添加此猴子补丁,该补丁在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
功能
就制作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
站在巨人和所有人的肩膀上
在我要从Rails 3.2升级到Rails 4之前, pluck_all
方法效果很好。
这是一个可解决此问题的宝石pluck_all ,不仅在Rails 3中而且在Rails 4和Rails 5中都支持pluck_all
方法。希望这对将要升级Rails版本的人有所帮助。
另一种选择是:
@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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.