簡體   English   中英

從ActiveRecord對象中提取兩個屬性的快捷方式?

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

我不喜歡以上兩件事

  1. 它將員工在映射之前加載到內存中,
  2. 它很冗長(我猜是主觀的)。

有沒有更好的辦法?

更新:

見@ 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

如果您確實需要較低級別的操作,只需查看使用select_all 的#pluck

在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

重命名從方法pluckpluck_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM