[英]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.